mu: Make commands Result-based
Use Result<void> as the return value, simplifying some code.
This commit is contained in:
@ -334,17 +334,17 @@ each_contact(const Mu::Contact& ci, ECData& ecdata)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MuError
|
static Result<void>
|
||||||
run_cmd_cfind(const Mu::Store& store,
|
run_cmd_cfind(const Mu::Store& store,
|
||||||
const char* pattern,
|
const char* pattern,
|
||||||
gboolean personal,
|
gboolean personal,
|
||||||
time_t after,
|
time_t after,
|
||||||
int maxnum,
|
int maxnum,
|
||||||
const MuConfigFormat format,
|
const MuConfigFormat format,
|
||||||
gboolean color,
|
gboolean color)
|
||||||
GError** err)
|
|
||||||
{
|
{
|
||||||
ECData ecdata{};
|
ECData ecdata{};
|
||||||
|
GError *err{};
|
||||||
|
|
||||||
memset(&ecdata, 0, sizeof(ecdata));
|
memset(&ecdata, 0, sizeof(ecdata));
|
||||||
|
|
||||||
@ -352,11 +352,10 @@ run_cmd_cfind(const Mu::Store& store,
|
|||||||
ecdata.rx = g_regex_new(
|
ecdata.rx = g_regex_new(
|
||||||
pattern,
|
pattern,
|
||||||
(GRegexCompileFlags)(G_REGEX_CASELESS | G_REGEX_OPTIMIZE),
|
(GRegexCompileFlags)(G_REGEX_CASELESS | G_REGEX_OPTIMIZE),
|
||||||
(GRegexMatchFlags)0,
|
(GRegexMatchFlags)0, &err);
|
||||||
err);
|
|
||||||
|
|
||||||
if (!ecdata.rx)
|
if (!ecdata.rx)
|
||||||
return MU_ERROR_CONTACTS;
|
return Err(Error::Code::Internal, &err, "invalid cfind regexp");
|
||||||
}
|
}
|
||||||
|
|
||||||
ecdata.personal = personal;
|
ecdata.personal = personal;
|
||||||
@ -378,17 +377,18 @@ run_cmd_cfind(const Mu::Store& store,
|
|||||||
if (ecdata.rx)
|
if (ecdata.rx)
|
||||||
g_regex_unref(ecdata.rx);
|
g_regex_unref(ecdata.rx);
|
||||||
|
|
||||||
if (ecdata.n == 0) {
|
if (ecdata.n == 0)
|
||||||
g_printerr("no matching contacts found\n");
|
return Err(Error::Code::ContactNotFound, "no matching contacts found");
|
||||||
return MU_ERROR_NO_MATCHES;
|
else
|
||||||
}
|
return Ok();
|
||||||
|
|
||||||
return MU_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
cfind_params_valid(const MuConfig* opts)
|
cfind_params_valid(const MuConfig* opts)
|
||||||
{
|
{
|
||||||
|
if (!opts || opts->cmd != MU_CONFIG_CMD_CFIND)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
switch (opts->format) {
|
switch (opts->format) {
|
||||||
case MU_CONFIG_FORMAT_PLAIN:
|
case MU_CONFIG_FORMAT_PLAIN:
|
||||||
case MU_CONFIG_FORMAT_MUTT_ALIAS:
|
case MU_CONFIG_FORMAT_MUTT_ALIAS:
|
||||||
@ -413,29 +413,17 @@ cfind_params_valid(const MuConfig* opts)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
MuError
|
Result<void>
|
||||||
Mu::mu_cmd_cfind(const Mu::Store& store, const MuConfig* opts, GError** err)
|
Mu::mu_cmd_cfind(const Mu::Store& store, const MuConfig* opts)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(opts, MU_ERROR_INTERNAL);
|
|
||||||
g_return_val_if_fail(opts->cmd == MU_CONFIG_CMD_CFIND, MU_ERROR_INTERNAL);
|
|
||||||
|
|
||||||
if (!cfind_params_valid(opts))
|
if (!cfind_params_valid(opts))
|
||||||
throw Mu::Error(Mu::Error::Code::InvalidArgument,
|
return Err(Error::Code::InvalidArgument, "error in parameters");
|
||||||
"invalid parameters");
|
else
|
||||||
|
return run_cmd_cfind(store,
|
||||||
auto res = run_cmd_cfind(store,
|
opts->params[1],
|
||||||
opts->params[1],
|
opts->personal,
|
||||||
opts->personal,
|
opts->after,
|
||||||
opts->after,
|
opts->maxnum,
|
||||||
opts->maxnum,
|
opts->format,
|
||||||
opts->format,
|
!opts->nocolor);
|
||||||
!opts->nocolor,
|
|
||||||
err);
|
|
||||||
|
|
||||||
if (res != MU_OK && res != MU_ERROR_NO_MATCHES)
|
|
||||||
throw Mu::Error(Mu::Error::Code::Internal,
|
|
||||||
err /*consumes*/,
|
|
||||||
"error in cfind");
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,7 @@ show_fields(const MuConfig* opts)
|
|||||||
|
|
||||||
Table fields;
|
Table fields;
|
||||||
fields.add_row({"field-name", "alias", "short", "search",
|
fields.add_row({"field-name", "alias", "short", "search",
|
||||||
"value", "example", "description"});
|
"value", "example query", "description"});
|
||||||
|
|
||||||
auto disp= [&](std::string_view sv)->std::string {
|
auto disp= [&](std::string_view sv)->std::string {
|
||||||
if (sv.empty())
|
if (sv.empty())
|
||||||
|
|||||||
@ -77,33 +77,20 @@ print_stats(const Indexer::Progress& stats, bool color)
|
|||||||
<< "; cleaned-up: " << col.fg(Color::Green) << stats.removed << col.reset();
|
<< "; cleaned-up: " << col.fg(Color::Green) << stats.removed << col.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
MuError
|
Result<void>
|
||||||
Mu::mu_cmd_index(Mu::Store& store, const MuConfig* opts, GError** err)
|
Mu::mu_cmd_index(Mu::Store& store, const MuConfig* opts)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(opts, MU_ERROR);
|
if (!opts || opts->cmd != MU_CONFIG_CMD_INDEX || opts->params[1])
|
||||||
g_return_val_if_fail(opts->cmd == MU_CONFIG_CMD_INDEX, MU_ERROR);
|
return Err(Error::Code::InvalidArgument, "error in parameters");
|
||||||
|
|
||||||
/* param[0] == 'index' there should be no param[1] */
|
if (opts->max_msg_size < 0)
|
||||||
if (opts->params[1]) {
|
return Err(Error::Code::InvalidArgument,
|
||||||
mu_util_g_set_error(err, MU_ERROR_IN_PARAMETERS, "unexpected parameter");
|
|
||||||
return MU_ERROR;
|
|
||||||
}
|
|
||||||
if (opts->max_msg_size < 0) {
|
|
||||||
mu_util_g_set_error(err,
|
|
||||||
MU_ERROR_IN_PARAMETERS,
|
|
||||||
"the maximum message size must be >= 0");
|
"the maximum message size must be >= 0");
|
||||||
return MU_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto mdir{store.properties().root_maildir};
|
const auto mdir{store.properties().root_maildir};
|
||||||
if (G_UNLIKELY(access(mdir.c_str(), R_OK) != 0)) {
|
if (G_UNLIKELY(access(mdir.c_str(), R_OK) != 0))
|
||||||
mu_util_g_set_error(err,
|
return Err(Error::Code::File, "'%s' is not readable: %s",
|
||||||
MU_ERROR_FILE,
|
mdir.c_str(), g_strerror(errno));
|
||||||
"'%s' is not readable: %s",
|
|
||||||
mdir.c_str(),
|
|
||||||
g_strerror(errno));
|
|
||||||
return MU_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
MaybeAnsi col{!opts->nocolor};
|
MaybeAnsi col{!opts->nocolor};
|
||||||
using Color = MaybeAnsi::Color;
|
using Color = MaybeAnsi::Color;
|
||||||
@ -146,5 +133,5 @@ Mu::mu_cmd_index(Mu::Store& store, const MuConfig* opts, GError** err)
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MU_OK;
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,20 +43,20 @@ using namespace Mu;
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
print_script(const char* name,
|
print_script(const char* name,
|
||||||
const char* oneline,
|
const char* oneline,
|
||||||
const char* descr,
|
const char* descr,
|
||||||
gboolean color,
|
gboolean color,
|
||||||
gboolean verbose)
|
gboolean verbose)
|
||||||
{
|
{
|
||||||
g_print("%s%s%s%s%s%s%s%s",
|
g_print("%s%s%s%s%s%s%s%s",
|
||||||
verbose ? "\n" : " * ",
|
verbose ? "\n" : " * ",
|
||||||
COL(MU_COLOR_GREEN),
|
COL(MU_COLOR_GREEN),
|
||||||
name,
|
name,
|
||||||
COL(MU_COLOR_DEFAULT),
|
COL(MU_COLOR_DEFAULT),
|
||||||
oneline ? ": " : "",
|
oneline ? ": " : "",
|
||||||
COL(MU_COLOR_BLUE),
|
COL(MU_COLOR_BLUE),
|
||||||
oneline ? oneline : "",
|
oneline ? oneline : "",
|
||||||
MU_COLOR_DEFAULT);
|
MU_COLOR_DEFAULT);
|
||||||
|
|
||||||
if (verbose && descr)
|
if (verbose && descr)
|
||||||
g_print("%s%s%s", COL(MU_COLOR_MAGENTA), descr, COL(MU_COLOR_DEFAULT));
|
g_print("%s%s%s", COL(MU_COLOR_MAGENTA), descr, COL(MU_COLOR_DEFAULT));
|
||||||
@ -109,10 +109,10 @@ get_userpath(const char* muhome)
|
|||||||
return g_build_path(G_DIR_SEPARATOR_S, muhome, "scripts", NULL);
|
return g_build_path(G_DIR_SEPARATOR_S, muhome, "scripts", NULL);
|
||||||
else
|
else
|
||||||
return g_build_path(G_DIR_SEPARATOR_S,
|
return g_build_path(G_DIR_SEPARATOR_S,
|
||||||
g_get_user_data_dir(),
|
g_get_user_data_dir(),
|
||||||
"mu",
|
"mu",
|
||||||
"scripts",
|
"scripts",
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GSList*
|
static GSList*
|
||||||
@ -122,9 +122,9 @@ get_script_info_list(const char* muhome, GError** err)
|
|||||||
char* userpath;
|
char* userpath;
|
||||||
|
|
||||||
scripts = mu_script_get_script_info_list(MU_SCRIPTS_DIR,
|
scripts = mu_script_get_script_info_list(MU_SCRIPTS_DIR,
|
||||||
MU_GUILE_EXT,
|
MU_GUILE_EXT,
|
||||||
MU_GUILE_DESCR_PREFIX,
|
MU_GUILE_DESCR_PREFIX,
|
||||||
err);
|
err);
|
||||||
|
|
||||||
if (err && *err)
|
if (err && *err)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -158,51 +158,44 @@ get_script_info_list(const char* muhome, GError** err)
|
|||||||
return userscripts; /* apparently, scripts was NULL */
|
return userscripts; /* apparently, scripts was NULL */
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
Mu::Result<void>
|
||||||
check_params(const MuConfig* opts, GError** err)
|
Mu::mu_cmd_script(const MuConfig* opts)
|
||||||
{
|
{
|
||||||
if (!mu_util_supports(MU_FEATURE_GUILE)) {
|
GError *err{};
|
||||||
mu_util_g_set_error(err,
|
MuScriptInfo* msi;
|
||||||
MU_ERROR_IN_PARAMETERS,
|
GSList* scripts;
|
||||||
"the 'script' command is not available "
|
|
||||||
"in this version of mu");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
if (!mu_util_supports(MU_FEATURE_GUILE))
|
||||||
}
|
return Err(Error::Code::InvalidArgument,
|
||||||
|
"<script> sub-command not available (requires guile)");
|
||||||
|
|
||||||
MuError
|
scripts = get_script_info_list(opts->muhome, &err);
|
||||||
Mu::mu_cmd_script(const MuConfig* opts, GError** err)
|
if (err)
|
||||||
{
|
|
||||||
MuScriptInfo* msi;
|
|
||||||
GSList* scripts;
|
|
||||||
|
|
||||||
g_return_val_if_fail(opts, MU_ERROR_INTERNAL);
|
|
||||||
g_return_val_if_fail(opts->cmd == MU_CONFIG_CMD_SCRIPT, MU_ERROR_INTERNAL);
|
|
||||||
|
|
||||||
if (!check_params(opts, err))
|
|
||||||
return MU_ERROR;
|
|
||||||
|
|
||||||
scripts = get_script_info_list(opts->muhome, err);
|
|
||||||
if (err && *err)
|
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
if (g_strcmp0(opts->cmdstr, "script") == 0) {
|
if (g_strcmp0(opts->cmdstr, "script") == 0) {
|
||||||
print_scripts(scripts, !opts->nocolor, opts->verbose, opts->script_params[0], err);
|
print_scripts(scripts, !opts->nocolor, opts->verbose,
|
||||||
|
opts->script_params[0], &err);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
msi = mu_script_find_script_with_name(scripts, opts->script);
|
msi = mu_script_find_script_with_name(scripts, opts->script);
|
||||||
if (!msi) {
|
if (!msi) {
|
||||||
mu_util_g_set_error(err, MU_ERROR_SCRIPT_NOT_FOUND, "command or script not found");
|
mu_util_g_set_error(&err, MU_ERROR_SCRIPT_NOT_FOUND,
|
||||||
|
"command or script not found");
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do it! */
|
/* do it! */
|
||||||
mu_script_guile_run(msi, mu_runtime_path(MU_RUNTIME_PATH_CACHE), opts->script_params, err);
|
mu_script_guile_run(msi, mu_runtime_path(MU_RUNTIME_PATH_CACHE),
|
||||||
|
opts->script_params, &err);
|
||||||
leave:
|
leave:
|
||||||
/* this won't be reached, unless there is some error */
|
/* this won't be reached, unless there is some error */
|
||||||
mu_script_info_list_destroy(scripts);
|
mu_script_info_list_destroy(scripts);
|
||||||
return (err && *err) ? MU_ERROR : MU_OK;
|
|
||||||
|
if (err)
|
||||||
|
return Err(Error::Code::InvalidArgument, &err,
|
||||||
|
"error running script");
|
||||||
|
else
|
||||||
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -113,12 +113,14 @@ report_error(const Mu::Error& err) noexcept
|
|||||||
Server::OutputFlags::Flush);
|
Server::OutputFlags::Flush);
|
||||||
}
|
}
|
||||||
|
|
||||||
MuError
|
|
||||||
Mu::mu_cmd_server(const MuConfig* opts, GError** err)
|
Result<void>
|
||||||
try {
|
Mu::mu_cmd_server(const MuConfig* opts) try {
|
||||||
auto store = Store::make(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB), Store::Options::Writable);
|
|
||||||
|
auto store = Store::make(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
|
||||||
|
Store::Options::Writable);
|
||||||
if (!store)
|
if (!store)
|
||||||
throw store.error();
|
return Err(store.error());
|
||||||
|
|
||||||
Server server{*store, output_sexp_stdout};
|
Server server{*store, output_sexp_stdout};
|
||||||
g_message("created server with store @ %s; maildir @ %s; debug-mode %s",
|
g_message("created server with store @ %s; maildir @ %s; debug-mode %s",
|
||||||
@ -132,7 +134,7 @@ try {
|
|||||||
: ""};
|
: ""};
|
||||||
if (!eval.empty()) {
|
if (!eval.empty()) {
|
||||||
server.invoke(eval);
|
server.invoke(eval);
|
||||||
return MU_OK;
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note, the readline stuff is inactive unless on a tty.
|
// Note, the readline stuff is inactive unless on a tty.
|
||||||
@ -155,15 +157,14 @@ try {
|
|||||||
}
|
}
|
||||||
shutdown_readline();
|
shutdown_readline();
|
||||||
|
|
||||||
return MU_OK;
|
return Ok();
|
||||||
|
|
||||||
} catch (const Error& er) {
|
} catch (const Error& er) {
|
||||||
/* note: user-level error, "OK" for mu */
|
/* note: user-level error, "OK" for mu */
|
||||||
report_error(er);
|
report_error(er);
|
||||||
g_warning("server caught exception: %s", er.what());
|
g_warning("server caught exception: %s", er.what());
|
||||||
return MU_OK;
|
return Ok();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
g_critical("server caught exception");
|
g_critical("server caught exception");
|
||||||
g_set_error(err, MU_ERROR_DOMAIN, MU_ERROR, "%s", "caught exception");
|
return Err(Error::Code::Internal, "caught exception");
|
||||||
return MU_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|||||||
324
mu/mu-cmd.cc
324
mu/mu-cmd.cc
@ -75,10 +75,10 @@ get_attach_str(const Message& message, const MuConfig* opts)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define color_maybe(C) \
|
#define color_maybe(C) \
|
||||||
do { \
|
do { \
|
||||||
if (color) \
|
if (color) \
|
||||||
fputs((C), stdout); \
|
fputs((C), stdout); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -212,129 +212,64 @@ cmd_view(const MuConfig* opts)
|
|||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
static MuError
|
static Mu::Result<void>
|
||||||
cmd_mkdir(const MuConfig* opts, GError** err)
|
cmd_mkdir(const MuConfig* opts)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
g_return_val_if_fail(opts, MU_ERROR_INTERNAL);
|
if (!opts->params[1])
|
||||||
g_return_val_if_fail(opts->cmd == MU_CONFIG_CMD_MKDIR, MU_ERROR_INTERNAL);
|
return Err(Error::Code::InvalidArgument,
|
||||||
|
"missing directory parameter");
|
||||||
if (!opts->params[1]) {
|
|
||||||
mu_util_g_set_error(err, MU_ERROR_IN_PARAMETERS, "missing directory parameter");
|
|
||||||
return MU_ERROR_IN_PARAMETERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; opts->params[i]; ++i) {
|
for (i = 1; opts->params[i]; ++i) {
|
||||||
if (auto&& res{maildir_mkdir(opts->params[i],
|
if (auto&& res =
|
||||||
opts->dirmode, FALSE)}; !res) {
|
maildir_mkdir(opts->params[i], opts->dirmode, FALSE); !res)
|
||||||
g_set_error(err, MU_ERROR_DOMAIN, MU_ERROR_FILE,
|
return res;
|
||||||
"%s", res.error().what());
|
|
||||||
return MU_ERROR_FILE_CANNOT_MKDIR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MU_OK;
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static Result<void>
|
||||||
check_file_okay(const char* path, gboolean cmd_add)
|
cmd_add(Mu::Store& store, const MuConfig* opts)
|
||||||
{
|
{
|
||||||
if (!g_path_is_absolute(path)) {
|
|
||||||
g_printerr("path is not absolute: %s\n", path);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd_add && access(path, R_OK) != 0) {
|
|
||||||
g_printerr("path is not readable: %s: %s\n", path, g_strerror(errno));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef bool (*ForeachMsgFunc)(Mu::Store& store, const char* path, GError** err);
|
|
||||||
|
|
||||||
static MuError
|
|
||||||
foreach_msg_file(Mu::Store& store, const MuConfig* opts, ForeachMsgFunc foreach_func, GError** err)
|
|
||||||
{
|
|
||||||
unsigned u;
|
|
||||||
gboolean all_ok;
|
|
||||||
|
|
||||||
/* note: params[0] will be 'add' */
|
/* note: params[0] will be 'add' */
|
||||||
if (!opts->params[0] || !opts->params[1]) {
|
if (!opts->params[0] || !opts->params[1])
|
||||||
g_print("usage: mu %s <file> [<files>]\n",
|
return Err(Error::Code::InvalidArgument,
|
||||||
opts->params[0] ? opts->params[0] : "<cmd>");
|
"expected some files to add");
|
||||||
mu_util_g_set_error(err, MU_ERROR_IN_PARAMETERS, "missing parameters");
|
|
||||||
return MU_ERROR_IN_PARAMETERS;
|
for (auto u = 1; opts->params[u]; ++u) {
|
||||||
|
|
||||||
|
const auto docid{store.add_message(opts->params[u])};
|
||||||
|
if (!docid)
|
||||||
|
return Err(docid.error());
|
||||||
|
else
|
||||||
|
g_debug("added message @ %s, docid=%u",
|
||||||
|
opts->params[u], docid.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u = 1, all_ok = TRUE; opts->params[u]; ++u) {
|
return Ok();
|
||||||
const char* path;
|
}
|
||||||
|
|
||||||
path = opts->params[u];
|
static Result<void>
|
||||||
|
cmd_remove(Mu::Store& store, const MuConfig* opts)
|
||||||
|
{
|
||||||
|
/* note: params[0] will be 'remove' */
|
||||||
|
if (!opts->params[0] || !opts->params[1])
|
||||||
|
return Err(Error::Code::InvalidArgument,
|
||||||
|
"expected some files to remove");
|
||||||
|
|
||||||
if (!check_file_okay(path, TRUE)) {
|
for (auto u = 1; opts->params[u]; ++u) {
|
||||||
all_ok = FALSE;
|
|
||||||
g_printerr("not a valid message file: %s\n", path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!foreach_func(store, path, err)) {
|
const auto res = store.remove_message(opts->params[u]);
|
||||||
all_ok = FALSE;
|
if (!res)
|
||||||
g_printerr("error with %s: %s\n",
|
return Err(Error::Code::File, "failed to remove %s",
|
||||||
path,
|
opts->params[u]);
|
||||||
(err && *err) ? (*err)->message : "something went wrong");
|
else
|
||||||
g_clear_error(err);
|
g_debug("removed message @ %s", opts->params[u]);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!all_ok) {
|
return Ok();
|
||||||
mu_util_g_set_error(err,
|
|
||||||
MU_ERROR_XAPIAN_STORE_FAILED,
|
|
||||||
"%s failed for some message(s)",
|
|
||||||
opts->params[0]);
|
|
||||||
return MU_ERROR_XAPIAN_STORE_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MU_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
add_path_func(Mu::Store& store, const char* path, GError** err)
|
|
||||||
{
|
|
||||||
const auto docid{store.add_message(path)};
|
|
||||||
g_debug("added message @ %s, docid=%u", path, docid.value());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static MuError
|
|
||||||
cmd_add(Mu::Store& store, const MuConfig* opts, GError** err)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail(opts, MU_ERROR_INTERNAL);
|
|
||||||
g_return_val_if_fail(opts->cmd == MU_CONFIG_CMD_ADD, MU_ERROR_INTERNAL);
|
|
||||||
|
|
||||||
return foreach_msg_file(store, opts, add_path_func, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
remove_path_func(Mu::Store& store, const char* path, GError** err)
|
|
||||||
{
|
|
||||||
const auto res = store.remove_message(path);
|
|
||||||
g_debug("removed %s (%s)", path, res ? "yes" : "no");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static MuError
|
|
||||||
cmd_remove(Mu::Store& store, const MuConfig* opts, GError** err)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail(opts, MU_ERROR_INTERNAL);
|
|
||||||
g_return_val_if_fail(opts->cmd == MU_CONFIG_CMD_REMOVE, MU_ERROR_INTERNAL);
|
|
||||||
|
|
||||||
return foreach_msg_file(store, opts, remove_path_func, err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -466,8 +401,8 @@ cmd_verify(const MuConfig* opts)
|
|||||||
"failed to verify one or more signatures");
|
"failed to verify one or more signatures");
|
||||||
}
|
}
|
||||||
|
|
||||||
static MuError
|
static Result<void>
|
||||||
cmd_info(const Mu::Store& store, const MuConfig* opts, GError** err)
|
cmd_info(const Mu::Store& store, const MuConfig* opts)
|
||||||
{
|
{
|
||||||
using namespace tabulate;
|
using namespace tabulate;
|
||||||
|
|
||||||
@ -510,30 +445,24 @@ cmd_info(const Mu::Store& store, const MuConfig* opts, GError** err)
|
|||||||
|
|
||||||
std::cout << info << '\n';
|
std::cout << info << '\n';
|
||||||
|
|
||||||
return MU_OK;
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
static MuError
|
static Result<void>
|
||||||
cmd_init(const MuConfig* opts, GError** err)
|
cmd_init(const MuConfig* opts)
|
||||||
{
|
{
|
||||||
/* not provided, nor could we find a good default */
|
/* not provided, nor could we find a good default */
|
||||||
if (!opts->maildir) {
|
if (!opts->maildir)
|
||||||
mu_util_g_set_error(err,
|
return Err(Error::Code::InvalidArgument,
|
||||||
MU_ERROR_IN_PARAMETERS,
|
"missing --maildir parameter and could "
|
||||||
"missing --maildir parameter and could "
|
"not determine default");
|
||||||
"not determine default");
|
|
||||||
return MU_ERROR_IN_PARAMETERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts->max_msg_size < 0) {
|
if (opts->max_msg_size < 0)
|
||||||
mu_util_g_set_error(err,
|
return Err(Error::Code::InvalidArgument,
|
||||||
MU_ERROR_IN_PARAMETERS,
|
"invalid value for max-message-size");
|
||||||
"invalid value for max-message-size");
|
else if (opts->batch_size < 0)
|
||||||
return MU_ERROR_IN_PARAMETERS;
|
return Err(Error::Code::InvalidArgument,
|
||||||
} else if (opts->batch_size < 0) {
|
"invalid value for batch-size");
|
||||||
mu_util_g_set_error(err, MU_ERROR_IN_PARAMETERS, "invalid value for batch-size");
|
|
||||||
return MU_ERROR_IN_PARAMETERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mu::Store::Config conf{};
|
Mu::Store::Config conf{};
|
||||||
conf.max_message_size = opts->max_msg_size;
|
conf.max_message_size = opts->max_msg_size;
|
||||||
@ -549,14 +478,14 @@ cmd_init(const MuConfig* opts, GError** err)
|
|||||||
auto store = Store::make_new(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
|
auto store = Store::make_new(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
|
||||||
opts->maildir, my_addrs, conf);
|
opts->maildir, my_addrs, conf);
|
||||||
if (!store)
|
if (!store)
|
||||||
throw store.error();
|
return Err(store.error());
|
||||||
|
|
||||||
if (!opts->quiet) {
|
if (!opts->quiet) {
|
||||||
cmd_info(*store, opts, NULL);
|
cmd_info(*store, opts);
|
||||||
std::cout << "\nstore created; use the 'index' command to fill/update it.\n";
|
std::cout << "\nstore created; use the 'index' command to fill/update it.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return MU_OK;
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result<void>
|
static Result<void>
|
||||||
@ -579,124 +508,95 @@ show_usage(void)
|
|||||||
"more information\n");
|
"more information\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef MuError (*readonly_store_func)(const Mu::Store&, const MuConfig*, GError** err);
|
|
||||||
typedef MuError (*writable_store_func)(Mu::Store&, const MuConfig*, GError** err);
|
|
||||||
|
|
||||||
static MuError
|
using ReadOnlyStoreFunc = std::function<Result<void>(const Store&, const MuConfig*)>;
|
||||||
with_readonly_store(readonly_store_func func, const MuConfig* opts, GError** err)
|
using WritableStoreFunc = std::function<Result<void>(Store&, const MuConfig*)>;
|
||||||
|
|
||||||
|
static Result<void>
|
||||||
|
with_readonly_store(const ReadOnlyStoreFunc& func, const MuConfig* opts)
|
||||||
{
|
{
|
||||||
auto store{Store::make(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB))};
|
auto store{Store::make(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB))};
|
||||||
if (!store)
|
if (!store)
|
||||||
throw store.error();
|
return Err(store.error());
|
||||||
|
|
||||||
return func(*store, opts, err);
|
return func(store.value(), opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MuError
|
static Result<void>
|
||||||
with_writable_store(writable_store_func func, const MuConfig* opts, GError** err)
|
with_writable_store(const WritableStoreFunc func, const MuConfig* opts)
|
||||||
{
|
{
|
||||||
auto store{Store::make(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
|
auto store{Store::make(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
|
||||||
Store::Options::Writable)};
|
Store::Options::Writable)};
|
||||||
if (!store)
|
if (!store)
|
||||||
throw store.error();
|
return Err(store.error());
|
||||||
|
|
||||||
return func(*store, opts, err);
|
return func(store.value(), opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
Result<void>
|
||||||
check_params(const MuConfig* opts, GError** err)
|
Mu::mu_cmd_execute(const MuConfig* opts) try {
|
||||||
{
|
|
||||||
if (!opts->params || !opts->params[0]) { /* no command? */
|
|
||||||
show_usage();
|
|
||||||
mu_util_g_set_error(err, MU_ERROR_IN_PARAMETERS,
|
|
||||||
"error in parameters");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
if (!opts || !opts->params || !opts->params[0])
|
||||||
}
|
return Err(Error::Code::InvalidArgument, "error in parameters");
|
||||||
|
|
||||||
MuError
|
|
||||||
Mu::mu_cmd_execute(const MuConfig* opts, GError** err) try {
|
|
||||||
|
|
||||||
MuError merr;
|
|
||||||
|
|
||||||
g_return_val_if_fail(opts, MU_ERROR_INTERNAL);
|
|
||||||
if (!check_params(opts, err))
|
|
||||||
return MU_G_ERROR_CODE(err);
|
|
||||||
|
|
||||||
auto mu_error_from_result = [](auto&& result, GError **gerr) {
|
|
||||||
if (result)
|
|
||||||
return MU_OK;
|
|
||||||
|
|
||||||
result.error().fill_g_error(gerr);
|
|
||||||
switch(result.error().code()) {
|
|
||||||
case Error::Code::NoMatches:
|
|
||||||
return MU_ERROR_NO_MATCHES;
|
|
||||||
case Error::Code::UnverifiedSignature:
|
|
||||||
return MU_ERROR_CRYPTO;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MU_ERROR;
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (opts->cmd) {
|
switch (opts->cmd) {
|
||||||
/* already handled in mu-config.c */
|
case MU_CONFIG_CMD_HELP: /* already handled in mu-config.c */
|
||||||
case MU_CONFIG_CMD_HELP:
|
return Ok();
|
||||||
return MU_OK;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* no store needed
|
* no store needed
|
||||||
*/
|
*/
|
||||||
case MU_CONFIG_CMD_FIELDS:
|
case MU_CONFIG_CMD_FIELDS:
|
||||||
merr = mu_error_from_result(mu_cmd_fields(opts), err);
|
return mu_cmd_fields(opts);
|
||||||
break;
|
case MU_CONFIG_CMD_MKDIR:
|
||||||
case MU_CONFIG_CMD_MKDIR: merr = cmd_mkdir(opts, err); break;
|
return cmd_mkdir(opts);
|
||||||
case MU_CONFIG_CMD_SCRIPT: merr = mu_cmd_script(opts, err); break;
|
case MU_CONFIG_CMD_SCRIPT:
|
||||||
|
return mu_cmd_script(opts);
|
||||||
case MU_CONFIG_CMD_VIEW:
|
case MU_CONFIG_CMD_VIEW:
|
||||||
merr = mu_error_from_result(cmd_view(opts), err);
|
return cmd_view(opts);
|
||||||
break;
|
case MU_CONFIG_CMD_VERIFY:
|
||||||
case MU_CONFIG_CMD_VERIFY: {
|
return cmd_verify(opts);
|
||||||
merr = mu_error_from_result(cmd_verify(opts), err);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MU_CONFIG_CMD_EXTRACT:
|
case MU_CONFIG_CMD_EXTRACT:
|
||||||
merr = mu_error_from_result(mu_cmd_extract(opts), err);
|
return mu_cmd_extract(opts);
|
||||||
break;
|
|
||||||
/*
|
/*
|
||||||
* read-only store
|
* read-only store
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case MU_CONFIG_CMD_CFIND: merr = with_readonly_store(mu_cmd_cfind, opts, err); break;
|
case MU_CONFIG_CMD_CFIND:
|
||||||
case MU_CONFIG_CMD_FIND:
|
return with_readonly_store(mu_cmd_cfind, opts);
|
||||||
merr = mu_error_from_result(cmd_find(opts), err);
|
|
||||||
break;
|
break;
|
||||||
|
case MU_CONFIG_CMD_FIND:
|
||||||
|
return cmd_find(opts);
|
||||||
case MU_CONFIG_CMD_INFO:
|
case MU_CONFIG_CMD_INFO:
|
||||||
merr = with_readonly_store(cmd_info, opts, err);
|
return with_readonly_store(cmd_info, opts);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* writable store */
|
/* writable store */
|
||||||
|
|
||||||
case MU_CONFIG_CMD_ADD: merr = with_writable_store(cmd_add, opts, err); break;
|
case MU_CONFIG_CMD_ADD:
|
||||||
case MU_CONFIG_CMD_REMOVE: merr = with_writable_store(cmd_remove, opts, err); break;
|
return with_writable_store(cmd_add, opts);
|
||||||
case MU_CONFIG_CMD_INDEX: merr = with_writable_store(mu_cmd_index, opts, err); break;
|
case MU_CONFIG_CMD_REMOVE:
|
||||||
|
return with_writable_store(cmd_remove, opts);
|
||||||
|
case MU_CONFIG_CMD_INDEX:
|
||||||
|
return with_writable_store(mu_cmd_index, opts);
|
||||||
|
|
||||||
/* commands instantiate store themselves */
|
/* commands instantiate store themselves */
|
||||||
case MU_CONFIG_CMD_INIT: merr = cmd_init(opts, err); break;
|
case MU_CONFIG_CMD_INIT:
|
||||||
case MU_CONFIG_CMD_SERVER: merr = mu_cmd_server(opts, err); break;
|
return cmd_init(opts);
|
||||||
|
case MU_CONFIG_CMD_SERVER:
|
||||||
|
return mu_cmd_server(opts);
|
||||||
|
|
||||||
default: merr = MU_ERROR_IN_PARAMETERS; break;
|
default:
|
||||||
|
show_usage();
|
||||||
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
return merr;
|
|
||||||
|
|
||||||
} catch (const Mu::Error& er) {
|
} catch (const Mu::Error& er) {
|
||||||
g_set_error(err, MU_ERROR_DOMAIN, MU_ERROR, "%s", er.what());
|
return Err(er);
|
||||||
return MU_ERROR;
|
} catch (const std::runtime_error& re) {
|
||||||
|
return Err(Error::Code::Internal, "runtime-error: %s", re.what());
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
return Err(Error::Code::Internal, "error: %s", ex.what());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
g_set_error(err, MU_ERROR_DOMAIN, MU_ERROR, "%s", "caught exception");
|
return Err(Error::Code::Internal, "caught exception");
|
||||||
return MU_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|||||||
39
mu/mu-cmd.hh
39
mu/mu-cmd.hh
@ -60,44 +60,29 @@ Result<void> mu_cmd_fields(const MuConfig* opts);
|
|||||||
* @param opts configuration options
|
* @param opts configuration options
|
||||||
* @param err receives error information, or NULL
|
* @param err receives error information, or NULL
|
||||||
*
|
*
|
||||||
* @return MU_OK (0) if the command succeeds,
|
* @return Ok() or some error
|
||||||
* some error code otherwise
|
|
||||||
*/
|
*/
|
||||||
MuError mu_cmd_script(const MuConfig* opts, GError** err);
|
Result<void> mu_cmd_script(const MuConfig* opts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* execute the cfind command
|
* execute the cfind command
|
||||||
*
|
*
|
||||||
* @param store store object to use
|
* @param store store object to use
|
||||||
* @param opts configuration options
|
* @param opts configuration options
|
||||||
* @param err receives error information, or NULL
|
|
||||||
*
|
*
|
||||||
* @return MU_OK (0) if the command succeeds,
|
* @return Ok() or some error
|
||||||
* some error code otherwise
|
|
||||||
*/
|
*/
|
||||||
MuError mu_cmd_cfind(const Mu::Store& store, const MuConfig* opts, GError** err);
|
Result<void> mu_cmd_cfind(const Mu::Store& store, const MuConfig* opts);
|
||||||
|
|
||||||
/**
|
|
||||||
* execute some mu command, based on 'opts'
|
|
||||||
*
|
|
||||||
* @param opts configuration option
|
|
||||||
* @param err receives error information, or NULL
|
|
||||||
*
|
|
||||||
* @return MU_OK if all went wall, some error code otherwise
|
|
||||||
*/
|
|
||||||
MuError mu_cmd_execute(const MuConfig* opts, GError** err);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* execute the 'index' command
|
* execute the 'index' command
|
||||||
*
|
*
|
||||||
* @param store store object to use
|
* @param store store object to use
|
||||||
* @param opts configuration options
|
* @param opts configuration options
|
||||||
* @param err receives error information, or NULL
|
|
||||||
*
|
*
|
||||||
* @return MU_OK (0) if the command succeeded,
|
* @return Ok() or some error
|
||||||
* some error code otherwise
|
|
||||||
*/
|
*/
|
||||||
MuError mu_cmd_index(Mu::Store& store, const MuConfig* opt, GError** err);
|
Result<void> mu_cmd_index(Mu::Store& store, const MuConfig* opt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* execute the server command
|
* execute the server command
|
||||||
@ -106,7 +91,17 @@ MuError mu_cmd_index(Mu::Store& store, const MuConfig* opt, GError** err);
|
|||||||
*
|
*
|
||||||
* @return MU_OK (0) if the command succeeds, some error code otherwise
|
* @return MU_OK (0) if the command succeeds, some error code otherwise
|
||||||
*/
|
*/
|
||||||
MuError mu_cmd_server(const MuConfig* opts, GError** err);
|
Result<void> mu_cmd_server(const MuConfig* opts);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* execute some mu command, based on 'opts'
|
||||||
|
*
|
||||||
|
* @param opts configuration option
|
||||||
|
* @param err receives error information, or NULL
|
||||||
|
*
|
||||||
|
* @return Ok() or some error
|
||||||
|
*/
|
||||||
|
Result<void> mu_cmd_execute(const MuConfig* opts);
|
||||||
|
|
||||||
} // namespace Mu
|
} // namespace Mu
|
||||||
|
|
||||||
|
|||||||
87
mu/mu.cc
87
mu/mu.cc
@ -44,90 +44,77 @@ show_version(void)
|
|||||||
g_print("%s\n", blurb);
|
g_print("%s\n", blurb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
handle_error(MuConfig* conf, MuError merr, GError** err)
|
handle_result(const Result<void>& res, MuConfig* conf)
|
||||||
{
|
{
|
||||||
if (!(err && *err))
|
if (res)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
using Color = MaybeAnsi::Color;
|
using Color = MaybeAnsi::Color;
|
||||||
MaybeAnsi col{conf ? !conf->nocolor : false};
|
MaybeAnsi col{conf ? !conf->nocolor : false};
|
||||||
|
|
||||||
if (*err)
|
// show the error and some help, but not if it's only a softerror.
|
||||||
|
if (!res.error().is_soft_error()) {
|
||||||
std::cerr << col.fg(Color::Red) << "error" << col.reset() << ": "
|
std::cerr << col.fg(Color::Red) << "error" << col.reset() << ": "
|
||||||
<< col.fg(Color::BrightYellow)
|
<< col.fg(Color::BrightYellow)
|
||||||
<< ((*err) ? (*err)->message : "something when wrong") << "\n";
|
<< res.error().what() << "something went wrong" << "\n";
|
||||||
|
} else
|
||||||
|
std::cerr << col.fg(Color::BrightBlue) << res.error().what() << '\n';
|
||||||
|
|
||||||
std::cerr << col.fg(Color::Green);
|
std::cerr << col.fg(Color::Green);
|
||||||
|
|
||||||
switch ((*err)->code) {
|
// perhaps give some useful hint on how to solve it.
|
||||||
case MU_ERROR_XAPIAN_CANNOT_GET_WRITELOCK:
|
switch (res.error().code()) {
|
||||||
std::cerr << "Maybe mu is already running?\n";
|
case Error::Code::InvalidArgument:
|
||||||
break;
|
|
||||||
|
|
||||||
case MU_ERROR_XAPIAN_NEEDS_REINDEX:
|
|
||||||
std::cerr << "Database needs (re)indexing.\n"
|
|
||||||
<< "try 'mu index' "
|
|
||||||
<< "(see mu-index(1) for details)\n";
|
|
||||||
return;
|
|
||||||
case MU_ERROR_IN_PARAMETERS:
|
|
||||||
if (conf && mu_config_cmd_is_valid(conf->cmd))
|
if (conf && mu_config_cmd_is_valid(conf->cmd))
|
||||||
mu_config_show_help(conf->cmd);
|
mu_config_show_help(conf->cmd);
|
||||||
break;
|
break;
|
||||||
case MU_ERROR_SCRIPT_NOT_FOUND:
|
case Error::Code::SchemaMismatch:
|
||||||
std::cerr << "See the mu manpage for commands, or "
|
std::cerr << "Please (re)initialize mu with 'mu init' "
|
||||||
<< "'mu script' for the scripts\n";
|
<< "see mu-init(1) for details\n";
|
||||||
break;
|
break;
|
||||||
case MU_ERROR_XAPIAN_CANNOT_OPEN:
|
default:
|
||||||
std::cerr << "Please (re)initialize mu with 'mu init' "
|
break; /* nothing to do */
|
||||||
<< "see mu-init(1) for details\n";
|
|
||||||
return;
|
|
||||||
case MU_ERROR_XAPIAN_SCHEMA_MISMATCH:
|
|
||||||
std::cerr << "Please (re)initialize mu with 'mu init' "
|
|
||||||
<< "see mu-init(1) for details\n";
|
|
||||||
return;
|
|
||||||
default: break; /* nothing to do */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << col.reset();
|
std::cerr << col.reset();
|
||||||
|
|
||||||
|
return res.error().exit_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char* argv[])
|
main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
GError* err;
|
int rv{};
|
||||||
MuError rv;
|
MuConfig *conf{};
|
||||||
MuConfig* conf;
|
GError* err{};
|
||||||
|
|
||||||
|
using Color = MaybeAnsi::Color;
|
||||||
|
MaybeAnsi col{conf ? !conf->nocolor : false};
|
||||||
|
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
|
|
||||||
err = NULL;
|
|
||||||
rv = MU_OK;
|
|
||||||
|
|
||||||
conf = mu_config_init(&argc, &argv, &err);
|
conf = mu_config_init(&argc, &argv, &err);
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
rv = err ? (MuError)err->code : MU_ERROR;
|
std::cerr << col.fg(Color::Red) << "error" << col.reset() << ": "
|
||||||
|
<< col.fg(Color::BrightYellow)
|
||||||
|
<< (err ? err->message : "something went wrong") << "\n";
|
||||||
|
rv = 1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else if (conf->version) {
|
} else if (conf->version) {
|
||||||
show_version();
|
show_version();
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
} else if (conf->cmd == MU_CONFIG_CMD_NONE) /* nothing to do */
|
||||||
|
goto cleanup;
|
||||||
/* nothing to do */
|
else if (!mu_runtime_init(conf->muhome, PACKAGE_NAME, conf->debug)) {
|
||||||
if (conf->cmd == MU_CONFIG_CMD_NONE)
|
std::cerr << col.fg(Color::Red) << "error initializing mu\n"
|
||||||
return 0;
|
<< col.reset();
|
||||||
|
rv = 2;
|
||||||
if (!mu_runtime_init(conf->muhome, PACKAGE_NAME, conf->debug)) {
|
} else
|
||||||
mu_config_uninit(conf);
|
rv = handle_result(mu_cmd_execute(conf), conf);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = mu_cmd_execute(conf, &err);
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
handle_error(conf, rv, &err);
|
|
||||||
g_clear_error(&err);
|
g_clear_error(&err);
|
||||||
|
|
||||||
mu_config_uninit(conf);
|
mu_config_uninit(conf);
|
||||||
mu_runtime_uninit();
|
mu_runtime_uninit();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user