mirror of https://github.com/djcb/mu.git
mu: convert command-line tools to c++
This commit is contained in:
parent
dd0cb3112a
commit
a9fab4abcc
|
@ -447,6 +447,7 @@ Store::in_transaction () const
|
|||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// C compat
|
||||
extern "C" {
|
||||
|
@ -1390,44 +1391,4 @@ mu_store_get_dirstamp (const MuStore *store, const char *dirpath, GError **err)
|
|||
return self(store)->dirstamp(dirpath);
|
||||
}
|
||||
|
||||
void
|
||||
mu_store_print_info (const MuStore *store, gboolean nocolor)
|
||||
{
|
||||
const auto green{nocolor ? "" : MU_COLOR_GREEN};
|
||||
const auto def{nocolor ? "" : MU_COLOR_DEFAULT};
|
||||
|
||||
std::cout << "database-path : "
|
||||
<< green << self(store)->database_path() << def << "\n"
|
||||
<< "messages in store : "
|
||||
<< green << self(store)->size() << def << "\n"
|
||||
<< "schema-version : "
|
||||
<< green << self(store)->schema_version() << def << "\n";
|
||||
|
||||
const auto created{mu_store_created (store)};
|
||||
const auto tstamp{localtime (&created)};
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat-y2k"
|
||||
char tbuf[64];
|
||||
strftime (tbuf, sizeof(tbuf), "%c", tstamp);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
std::cout << "created : " << green << tbuf << def << "\n"
|
||||
<< "maildir : "
|
||||
<< green << self(store)->root_maildir() << def << "\n";
|
||||
|
||||
std::cout << ("personal-addresses : ");
|
||||
|
||||
auto addrs{mu_store_personal_addresses (store)};
|
||||
if (!addrs || g_strv_length(addrs) == 0)
|
||||
std::cout << green << "<none>" << def << "\n";
|
||||
else {
|
||||
for (auto i = 0U; addrs[i]; ++i) {
|
||||
std::cout << (i != 0 ? " " : "")
|
||||
<< green << addrs[i] << def << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev(addrs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,18 +195,8 @@ Sexp::Node::to_string () const
|
|||
break;
|
||||
}
|
||||
case Type::String:
|
||||
//sstrm << quote(value());
|
||||
sstrm << "\"";
|
||||
for (auto&& k: value()) {
|
||||
switch (k) {
|
||||
case '"' : sstrm << "\\\""; break;
|
||||
case '\\': sstrm << "\\\\"; break;
|
||||
default: sstrm << k;
|
||||
}
|
||||
}
|
||||
sstrm << "\"";
|
||||
sstrm << quote(value());
|
||||
break;
|
||||
|
||||
case Type::Number:
|
||||
case Type::Symbol:
|
||||
default:
|
||||
|
|
|
@ -309,7 +309,7 @@ typedef gpointer XapianEnquire;
|
|||
} while (0)
|
||||
|
||||
|
||||
#define MU_G_ERROR_CODE(GE) ((GE)&&(*(GE))?(*(GE))->code:MU_ERROR)
|
||||
#define MU_G_ERROR_CODE(GE) ((GE)&&(*(GE))?(MuError)(*(GE))->code:MU_ERROR)
|
||||
|
||||
|
||||
enum _MuError {
|
||||
|
|
|
@ -165,14 +165,17 @@ Mu::split (const std::string& str, const std::string& sepa)
|
|||
std::string
|
||||
Mu::quote (const std::string& str)
|
||||
{
|
||||
char *s = g_strescape (str.c_str(), NULL);
|
||||
if (!s)
|
||||
return {};
|
||||
std::string res{"\""};
|
||||
|
||||
std::string res (s);
|
||||
g_free (s);
|
||||
for (auto&& k: str) {
|
||||
switch (k) {
|
||||
case '"' : res += "\\\""; break;
|
||||
case '\\': res += "\\\\"; break;
|
||||
default: res += k;
|
||||
}
|
||||
}
|
||||
|
||||
return "\"" + res + "\"";
|
||||
return res + "\"";
|
||||
}
|
||||
|
||||
std::string
|
||||
|
|
|
@ -65,7 +65,7 @@ std::vector<std::string> split (const std::string& str,
|
|||
const std::string& sepa);
|
||||
|
||||
/**
|
||||
* Quote & escape a string
|
||||
* Quote & escape a string for " and \
|
||||
*
|
||||
* @param str a string
|
||||
*
|
||||
|
|
|
@ -21,21 +21,14 @@ AM_CPPFLAGS= \
|
|||
$(GLIB_CFLAGS) \
|
||||
$(CODE_COVERAGE_CFLAGS)
|
||||
|
||||
# don't use -Werror, as it might break on other compilers
|
||||
# use -Wno-unused-parameters, because some callbacks may not
|
||||
# really need all the params they get
|
||||
AM_CFLAGS= \
|
||||
$(JSON_GLIB_CFLAGS) \
|
||||
$(ASAN_CFLAGS) \
|
||||
$(WARN_CFLAGS) \
|
||||
$(CODE_COVERAGE_CFLAGS) \
|
||||
-Wno-switch-enum \
|
||||
-DMU_SCRIPTS_DIR="\"$(pkgdatadir)/scripts/\""
|
||||
|
||||
AM_CXXFLAGS= \
|
||||
$(JSON_GLIB_CFLAGS) \
|
||||
-DMU_SCRIPTS_DIR="\"$(pkgdatadir)/scripts/\""
|
||||
$(ASAN_CXXCFLAGS) \
|
||||
$(WARN_CXXFLAGS) \
|
||||
$(CODE_COVERAGE_CFLAGS)
|
||||
$(CODE_COVERAGE_CFLAGS) \
|
||||
-Wno-switch-enum
|
||||
|
||||
|
||||
AM_LDFLAGS= \
|
||||
$(ASAN_LDFLAGS)
|
||||
|
@ -47,16 +40,16 @@ bin_PROGRAMS= \
|
|||
# be linked as c++, not c.
|
||||
mu_SOURCES= \
|
||||
mu.cc \
|
||||
mu-cmd-cfind.c \
|
||||
mu-config.c \
|
||||
mu-config.h \
|
||||
mu-cmd-extract.c \
|
||||
mu-cmd-find.c \
|
||||
mu-cmd-index.c \
|
||||
mu-cmd-cfind.cc \
|
||||
mu-config.cc \
|
||||
mu-config.hh \
|
||||
mu-cmd-extract.cc \
|
||||
mu-cmd-find.cc \
|
||||
mu-cmd-index.cc \
|
||||
mu-cmd-server.cc \
|
||||
mu-cmd-script.c \
|
||||
mu-cmd.c \
|
||||
mu-cmd.h
|
||||
mu-cmd-script.cc \
|
||||
mu-cmd.cc \
|
||||
mu-cmd.hh
|
||||
|
||||
BUILT_SOURCES= \
|
||||
mu-help-strings.h
|
||||
|
@ -77,8 +70,8 @@ EXTRA_DIST= \
|
|||
|
||||
noinst_PROGRAMS= $(TEST_PROGS)
|
||||
|
||||
test_cflags= \
|
||||
${AM_CFLAGS} \
|
||||
test_cxxflags= \
|
||||
${AM_CXXFLAGS} \
|
||||
-DMU_TESTMAILDIR=\"${abs_top_srcdir}/lib/testdir\" \
|
||||
-DMU_TESTMAILDIR2=\"${abs_top_srcdir}/lib/testdir2\" \
|
||||
-DMU_TESTMAILDIR3=\"${abs_top_srcdir}/lib/testdir3\" \
|
||||
|
@ -88,31 +81,25 @@ test_cflags= \
|
|||
-DABS_SRCDIR=\"${abs_srcdir}\"
|
||||
|
||||
TEST_PROGS += test-mu-query
|
||||
test_mu_query_SOURCES= test-mu-query.c dummy.cc
|
||||
test_mu_query_CFLAGS=$(test_cflags)
|
||||
test_mu_query_SOURCES= test-mu-query.cc
|
||||
test_mu_query_CXXFLAGS=$(test_cxxflags)
|
||||
test_mu_query_LDADD=${top_builddir}/lib/libtestmucommon.la $(CODE_COVERAGE_LIBS)
|
||||
|
||||
TEST_PROGS += test-mu-cmd
|
||||
test_mu_cmd_SOURCES= test-mu-cmd.c dummy.cc
|
||||
test_mu_cmd_CFLAGS=$(test_cflags)
|
||||
test_mu_cmd_SOURCES= test-mu-cmd.cc
|
||||
test_mu_cmd_CXXFLAGS=$(test_cxxflags)
|
||||
test_mu_cmd_LDADD=${top_builddir}/lib/libtestmucommon.la $(CODE_COVERAGE_LIBS)
|
||||
|
||||
TEST_PROGS += test-mu-cmd-cfind
|
||||
test_mu_cmd_cfind_SOURCES= test-mu-cmd-cfind.c dummy.cc
|
||||
test_mu_cmd_cfind_CFLAGS=$(test_cflags)
|
||||
test_mu_cmd_cfind_SOURCES= test-mu-cmd-cfind.cc
|
||||
test_mu_cmd_cfind_CXXFLAGS=$(test_cxxflags)
|
||||
test_mu_cmd_cfind_LDADD=${top_builddir}/lib/libtestmucommon.la $(CODE_COVERAGE_LIBS)
|
||||
|
||||
TEST_PROGS += test-mu-threads
|
||||
test_mu_threads_SOURCES= test-mu-threads.c dummy.cc
|
||||
test_mu_threads_CFLAGS=$(test_cflags)
|
||||
test_mu_threads_SOURCES= test-mu-threads.cc
|
||||
test_mu_threads_CXXFLAGS=$(test_cxxflags)
|
||||
test_mu_threads_LDADD=${top_builddir}/lib/libtestmucommon.la $(CODE_COVERAGE_LIBS)
|
||||
|
||||
# we need to use dummy.cc to enforce c++ linking...
|
||||
BUILT_SOURCES+= \
|
||||
dummy.cc
|
||||
dummy.cc:
|
||||
touch dummy.cc
|
||||
|
||||
TESTS=$(TEST_PROGS)
|
||||
include $(top_srcdir)/aminclude_static.am
|
||||
|
||||
|
|
|
@ -18,16 +18,20 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "mu-cmd.h"
|
||||
#include "mu-cmd.hh"
|
||||
#include "mu-contacts.hh"
|
||||
#include "mu-runtime.h"
|
||||
|
||||
#include "utils/mu-util.h"
|
||||
#include "utils/mu-utils.hh"
|
||||
#include "utils/mu-error.hh"
|
||||
#include "utils/mu-str.h"
|
||||
#include "utils/mu-date.h"
|
||||
|
||||
|
@ -174,10 +178,8 @@ leave:
|
|||
return nick;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
print_header (MuConfigFormat format)
|
||||
print_header (const MuConfigFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case MU_CONFIG_FORMAT_BBDB:
|
||||
|
@ -193,18 +195,18 @@ print_header (MuConfigFormat format)
|
|||
}
|
||||
|
||||
static void
|
||||
each_contact_bbdb (const char *email, const char *name, time_t tstamp)
|
||||
each_contact_bbdb (const std::string& email, const std::string& name, time_t tstamp)
|
||||
{
|
||||
char *fname, *lname, *now, *timestamp;
|
||||
|
||||
fname = guess_first_name (name);
|
||||
lname = guess_last_name (name);
|
||||
fname = guess_first_name (name.c_str());
|
||||
lname = guess_last_name (name.c_str());
|
||||
now = mu_date_str ("%Y-%m-%d", time(NULL));
|
||||
timestamp = mu_date_str ("%Y-%m-%d", tstamp);
|
||||
|
||||
g_print ("[\"%s\" \"%s\" nil nil nil nil (\"%s\") "
|
||||
"((creation-date . \"%s\") (time-stamp . \"%s\")) nil]\n",
|
||||
fname, lname, email, now, timestamp);
|
||||
fname, lname, email.c_str(), now, timestamp);
|
||||
|
||||
g_free (now);
|
||||
g_free (timestamp);
|
||||
|
@ -214,89 +216,44 @@ each_contact_bbdb (const char *email, const char *name, time_t tstamp)
|
|||
|
||||
|
||||
static void
|
||||
each_contact_mutt_alias (const char *email, const char *name,
|
||||
each_contact_mutt_alias (const std::string& email, const std::string& name,
|
||||
GHashTable *nicks)
|
||||
{
|
||||
|
||||
gchar *nick;
|
||||
|
||||
if (!name)
|
||||
if (name.empty())
|
||||
return;
|
||||
|
||||
nick = guess_nick (name, nicks);
|
||||
char *nick = guess_nick (name.c_str(), nicks);
|
||||
mu_util_print_encoded ("alias %s %s <%s>\n",
|
||||
nick, name, email);
|
||||
g_free (nick);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
each_contact_wl (const char *email, const char *name, GHashTable *nicks)
|
||||
{
|
||||
gchar *nick;
|
||||
|
||||
if (!name)
|
||||
return;
|
||||
|
||||
nick = guess_nick (name, nicks);
|
||||
mu_util_print_encoded ("%s \"%s\" \"%s\"\n",
|
||||
email, nick, name);
|
||||
nick, name.c_str(), email.c_str());
|
||||
g_free (nick);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
each_contact_org_contact (const char *email, const char *name)
|
||||
each_contact_wl (const std::string& email, const std::string& name, GHashTable *nicks)
|
||||
{
|
||||
if (name)
|
||||
mu_util_print_encoded (
|
||||
"* %s\n:PROPERTIES:\n:EMAIL: %s\n:END:\n\n",
|
||||
name, email);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_csv_field (const char *str)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (!str)
|
||||
if (name.empty())
|
||||
return;
|
||||
|
||||
s = mu_str_replace (str, "\"", "\"\"");
|
||||
if (strchr (s, ','))
|
||||
mu_util_print_encoded ("\"%s\"", s);
|
||||
else
|
||||
mu_util_print_encoded ("%s", s);
|
||||
|
||||
g_free (s);
|
||||
char *nick = guess_nick (name.c_str(), nicks);
|
||||
mu_util_print_encoded ("%s \"%s\" \"%s\"\n", email.c_str(), nick, name.c_str());
|
||||
g_free (nick);
|
||||
}
|
||||
|
||||
static void
|
||||
each_contact_csv (const char *email, const char *name)
|
||||
print_plain (const std::string& email, const std::string& name, bool color)
|
||||
{
|
||||
print_csv_field (name);
|
||||
mu_util_print_encoded (",");
|
||||
print_csv_field (email);
|
||||
mu_util_print_encoded ("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
print_plain (const char *email, const char *name, gboolean color)
|
||||
{
|
||||
if (name) {
|
||||
if (color) fputs (MU_COLOR_MAGENTA, stdout);
|
||||
mu_util_fputs_encoded (name, stdout);
|
||||
fputs (" ", stdout);
|
||||
if (!name.empty()) {
|
||||
if (color)
|
||||
::fputs (MU_COLOR_MAGENTA, stdout);
|
||||
mu_util_fputs_encoded (name.c_str(), stdout);
|
||||
::fputs (" ", stdout);
|
||||
}
|
||||
|
||||
if (color)
|
||||
fputs (MU_COLOR_GREEN, stdout);
|
||||
::fputs (MU_COLOR_GREEN, stdout);
|
||||
|
||||
mu_util_fputs_encoded (email, stdout);
|
||||
mu_util_fputs_encoded (email.c_str(), stdout);
|
||||
|
||||
if (color)
|
||||
fputs (MU_COLOR_DEFAULT, stdout);
|
||||
|
@ -304,92 +261,91 @@ print_plain (const char *email, const char *name, gboolean color)
|
|||
fputs ("\n", stdout);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
MuConfigFormat format;
|
||||
gboolean color, personal;
|
||||
time_t after;
|
||||
struct ECData {
|
||||
MuConfigFormat format;
|
||||
gboolean color, personal;
|
||||
time_t after;
|
||||
GRegex *rx;
|
||||
GHashTable *nicks;
|
||||
size_t n;
|
||||
} ECData;
|
||||
|
||||
};
|
||||
|
||||
static void
|
||||
each_contact (const char *full_address,
|
||||
const char *email, const char *name, gboolean personal,
|
||||
time_t last_seen, size_t freq, gint64 tstamp,
|
||||
ECData *ecdata)
|
||||
each_contact (const Mu::ContactInfo& ci, ECData& ecdata)
|
||||
{
|
||||
if (ecdata->personal && !personal)
|
||||
if (ecdata.personal && ci.personal)
|
||||
return;
|
||||
|
||||
if (tstamp < ecdata->after)
|
||||
if (ci.tstamp < ecdata.after)
|
||||
return;
|
||||
|
||||
if (ecdata->rx &&
|
||||
!g_regex_match (ecdata->rx, email, 0, NULL) &&
|
||||
!g_regex_match (ecdata->rx, name ? name : "", 0, NULL))
|
||||
if (ecdata.rx &&
|
||||
!g_regex_match (ecdata.rx, ci.email.c_str(), (GRegexMatchFlags)0, NULL) &&
|
||||
!g_regex_match (ecdata.rx, ci.name.empty() ? "" : ci.name.c_str(), (GRegexMatchFlags)0, NULL))
|
||||
return;
|
||||
|
||||
++ecdata->n;
|
||||
++ecdata.n;
|
||||
|
||||
switch (ecdata->format) {
|
||||
switch (ecdata.format) {
|
||||
case MU_CONFIG_FORMAT_MUTT_ALIAS:
|
||||
each_contact_mutt_alias (email, name, ecdata->nicks);
|
||||
each_contact_mutt_alias (ci.email, ci.name, ecdata.nicks);
|
||||
break;
|
||||
case MU_CONFIG_FORMAT_MUTT_AB:
|
||||
mu_util_print_encoded ("%s\t%s\t\n",
|
||||
email, name ? name : "");
|
||||
ci.email.c_str(), ci.name.c_str());
|
||||
break;
|
||||
case MU_CONFIG_FORMAT_WL:
|
||||
each_contact_wl (email, name, ecdata->nicks);
|
||||
each_contact_wl (ci.email, ci.name, ecdata.nicks);
|
||||
break;
|
||||
case MU_CONFIG_FORMAT_ORG_CONTACT:
|
||||
each_contact_org_contact (email, name);
|
||||
if (!ci.name.empty())
|
||||
mu_util_print_encoded("* %s\n:PROPERTIES:\n:EMAIL: %s\n:END:\n\n",
|
||||
ci.name.c_str(), ci.email.c_str());
|
||||
break;
|
||||
case MU_CONFIG_FORMAT_BBDB:
|
||||
each_contact_bbdb (email, name, last_seen);
|
||||
each_contact_bbdb (ci.email, ci.name, ci.last_seen);
|
||||
break;
|
||||
case MU_CONFIG_FORMAT_CSV:
|
||||
each_contact_csv (email, name);
|
||||
mu_util_print_encoded("%s,%s\n",
|
||||
ci.name.empty() ? "" : Mu::quote(ci.name).c_str(),
|
||||
Mu::quote(ci.email).c_str());
|
||||
break;
|
||||
case MU_CONFIG_FORMAT_DEBUG: {
|
||||
char datebuf[32];
|
||||
strftime(datebuf, sizeof(datebuf), "%F %T",
|
||||
gmtime(&last_seen));
|
||||
gmtime(&ci.last_seen));
|
||||
g_print ("%s\n\tname: %s\n\t%s\n\tpersonal: %s\n\tfreq: %zu\n"
|
||||
"\tlast-seen: %s\n",
|
||||
email,
|
||||
name ? name : "<none>",
|
||||
full_address,
|
||||
personal ? "yes" : "no",
|
||||
freq,
|
||||
ci.email.c_str(),
|
||||
ci.name.empty() ? "<none>" : ci.name.c_str(),
|
||||
ci.full_address.c_str(),
|
||||
ci.personal ? "yes" : "no",
|
||||
ci.freq,
|
||||
datebuf);
|
||||
} break;
|
||||
default:
|
||||
print_plain (email, name, ecdata->color);
|
||||
print_plain (ci.email, ci.name, ecdata.color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static MuError
|
||||
run_cmd_cfind (MuStore *store,
|
||||
const char* pattern,
|
||||
gboolean personal,
|
||||
time_t after,
|
||||
MuConfigFormat format,
|
||||
gboolean color,
|
||||
GError **err)
|
||||
run_cmd_cfind (const Mu::Store& store,
|
||||
const char* pattern,
|
||||
gboolean personal,
|
||||
time_t after,
|
||||
const MuConfigFormat format,
|
||||
gboolean color,
|
||||
GError **err)
|
||||
{
|
||||
gboolean rv;
|
||||
ECData ecdata;
|
||||
ECData ecdata{};
|
||||
|
||||
memset(&ecdata, 0, sizeof(ecdata));
|
||||
|
||||
if (pattern) {
|
||||
ecdata.rx = g_regex_new (pattern,
|
||||
G_REGEX_CASELESS|G_REGEX_OPTIMIZE,
|
||||
0, err);
|
||||
(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE),
|
||||
(GRegexMatchFlags)0, err);
|
||||
if (!ecdata.rx)
|
||||
return MU_ERROR_CONTACTS;
|
||||
}
|
||||
|
@ -403,8 +359,9 @@ run_cmd_cfind (MuStore *store,
|
|||
g_free, NULL);
|
||||
|
||||
print_header (format);
|
||||
rv = mu_contacts_foreach (mu_store_contacts(store),
|
||||
(MuContactsForeachFunc)each_contact, &ecdata);
|
||||
|
||||
store.contacts().for_each([&](const auto& ci) { each_contact(ci, ecdata); });
|
||||
|
||||
g_hash_table_unref (ecdata.nicks);
|
||||
|
||||
if (ecdata.rx)
|
||||
|
@ -415,11 +372,11 @@ run_cmd_cfind (MuStore *store,
|
|||
return MU_ERROR_NO_MATCHES;
|
||||
}
|
||||
|
||||
return rv ? MU_OK : MU_ERROR_CONTACTS;
|
||||
return MU_OK;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cfind_params_valid (MuConfig *opts)
|
||||
cfind_params_valid (const MuConfig *opts)
|
||||
{
|
||||
switch (opts->format) {
|
||||
case MU_CONFIG_FORMAT_PLAIN:
|
||||
|
@ -447,24 +404,25 @@ cfind_params_valid (MuConfig *opts)
|
|||
}
|
||||
|
||||
MuError
|
||||
mu_cmd_cfind (MuStore *store, MuConfig *opts, GError **err)
|
||||
mu_cmd_cfind (const Mu::Store& store, const MuConfig *opts, GError **err)
|
||||
{
|
||||
g_return_val_if_fail (store, MU_ERROR_INTERNAL);
|
||||
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)) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_IN_PARAMETERS,
|
||||
"invalid parameters");
|
||||
return MU_ERROR_IN_PARAMETERS;
|
||||
}
|
||||
if (!cfind_params_valid (opts))
|
||||
throw Mu::Error(Mu::Error::Code::InvalidArgument,
|
||||
"invalid parameters");
|
||||
|
||||
return run_cmd_cfind (store,
|
||||
opts->params[1],
|
||||
opts->personal,
|
||||
opts->after,
|
||||
opts->format,
|
||||
!opts->nocolor,
|
||||
err);
|
||||
auto res = run_cmd_cfind (store,
|
||||
opts->params[1],
|
||||
opts->personal,
|
||||
opts->after,
|
||||
opts->format,
|
||||
!opts->nocolor,
|
||||
err);
|
||||
if (res != MU_OK)
|
||||
throw Mu::Error(Mu::Error::Code::Internal, err/*consumes*/,
|
||||
"error in cfind");
|
||||
return MU_OK;
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/
|
||||
|
||||
/*
|
||||
** Copyright (C) 2010-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
** Copyright (C) 2010-2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the GNU General Public License as published by the
|
||||
|
@ -19,22 +17,20 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mu-msg.h"
|
||||
#include "mu-msg-part.h"
|
||||
#include "mu-cmd.h"
|
||||
#include "mu-cmd.hh"
|
||||
#include "utils/mu-util.h"
|
||||
#include "utils/mu-str.h"
|
||||
|
||||
|
||||
static gboolean
|
||||
save_part (MuMsg *msg, const char *targetdir, guint partidx, MuConfig *opts)
|
||||
save_part (MuMsg *msg, const char *targetdir, guint partidx, const MuConfig *opts)
|
||||
{
|
||||
GError *err;
|
||||
gchar *filepath;
|
||||
|
@ -70,7 +66,7 @@ exit:
|
|||
|
||||
|
||||
static gboolean
|
||||
save_numbered_parts (MuMsg *msg, MuConfig *opts)
|
||||
save_numbered_parts (MuMsg *msg, const MuConfig *opts)
|
||||
{
|
||||
gboolean rv;
|
||||
char **parts, **cur;
|
||||
|
@ -116,8 +112,9 @@ anchored_regex (const char* pattern)
|
|||
pattern[strlen(pattern)-1] == '$' ? "" : "$");
|
||||
|
||||
err = NULL;
|
||||
rx = g_regex_new (anchored, G_REGEX_CASELESS|G_REGEX_OPTIMIZE, 0,
|
||||
&err);
|
||||
rx = g_regex_new (anchored,
|
||||
(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE),
|
||||
(GRegexMatchFlags)0, &err);
|
||||
g_free (anchored);
|
||||
|
||||
if (!rx) {
|
||||
|
@ -132,7 +129,7 @@ anchored_regex (const char* pattern)
|
|||
|
||||
|
||||
static gboolean
|
||||
save_part_with_filename (MuMsg *msg, const char *pattern, MuConfig *opts)
|
||||
save_part_with_filename (MuMsg *msg, const char *pattern, const MuConfig *opts)
|
||||
{
|
||||
GSList *lst, *cur;
|
||||
GRegex *rx;
|
||||
|
@ -164,7 +161,7 @@ save_part_with_filename (MuMsg *msg, const char *pattern, MuConfig *opts)
|
|||
struct _SaveData {
|
||||
gboolean result;
|
||||
guint saved_num;
|
||||
MuConfig *opts;
|
||||
const MuConfig *opts;
|
||||
};
|
||||
typedef struct _SaveData SaveData;
|
||||
|
||||
|
@ -232,7 +229,7 @@ exit:
|
|||
}
|
||||
|
||||
static gboolean
|
||||
save_certain_parts (MuMsg *msg, MuConfig *opts)
|
||||
save_certain_parts (MuMsg *msg, const MuConfig *opts)
|
||||
{
|
||||
SaveData sd;
|
||||
MuMsgOptions msgopts;
|
||||
|
@ -256,7 +253,7 @@ save_certain_parts (MuMsg *msg, MuConfig *opts)
|
|||
|
||||
|
||||
static gboolean
|
||||
save_parts (const char *path, const char *filename, MuConfig *opts)
|
||||
save_parts (const char *path, const char *filename, const MuConfig *opts)
|
||||
{
|
||||
MuMsg* msg;
|
||||
gboolean rv;
|
||||
|
@ -336,7 +333,7 @@ each_part_show (MuMsg *msg, MuMsgPart *part, gboolean color)
|
|||
|
||||
|
||||
static gboolean
|
||||
show_parts (const char* path, MuConfig *opts, GError **err)
|
||||
show_parts (const char* path, const MuConfig *opts, GError **err)
|
||||
{
|
||||
MuMsg *msg;
|
||||
MuMsgOptions msgopts;
|
||||
|
@ -362,7 +359,7 @@ show_parts (const char* path, MuConfig *opts, GError **err)
|
|||
|
||||
|
||||
static gboolean
|
||||
check_params (MuConfig *opts, GError **err)
|
||||
check_params (const MuConfig *opts, GError **err)
|
||||
{
|
||||
size_t param_num;
|
||||
|
||||
|
@ -396,7 +393,7 @@ check_params (MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
MuError
|
||||
mu_cmd_extract (MuConfig *opts, GError **err)
|
||||
mu_cmd_extract (const MuConfig *opts, GError **err)
|
||||
{
|
||||
int rv;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** Copyright (C) 2008-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
** Copyright (C) 2008-2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the GNU General Public License as published by the
|
||||
|
@ -17,9 +17,7 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
@ -40,7 +38,7 @@
|
|||
#include "utils/mu-str.h"
|
||||
#include "utils/mu-date.h"
|
||||
|
||||
#include "mu-cmd.h"
|
||||
#include "mu-cmd.hh"
|
||||
#include "mu-threader.h"
|
||||
|
||||
#ifdef HAVE_JSON_GLIB
|
||||
|
@ -48,7 +46,7 @@
|
|||
#endif /*HAVE_JSON_GLIB*/
|
||||
|
||||
typedef gboolean (OutputFunc) (MuMsg *msg, MuMsgIter *iter,
|
||||
MuConfig *opts, GError **err);
|
||||
const MuConfig *opts, GError **err);
|
||||
|
||||
static gboolean
|
||||
print_internal (MuQuery *query, const gchar *expr, gboolean xapian,
|
||||
|
@ -115,11 +113,11 @@ get_message (MuMsgIter *iter, time_t after)
|
|||
}
|
||||
|
||||
static MuMsgIter*
|
||||
run_query (MuQuery *xapian, const gchar *query, MuConfig *opts, GError **err)
|
||||
run_query (MuQuery *xapian, const gchar *query, const MuConfig *opts, GError **err)
|
||||
{
|
||||
MuMsgIter *iter;
|
||||
MuMsgFieldId sortid;
|
||||
MuQueryFlags qflags;
|
||||
MuMsgIter *iter;
|
||||
MuMsgFieldId sortid;
|
||||
int qflags;
|
||||
|
||||
sortid = MU_MSG_FIELD_ID_NONE;
|
||||
if (opts->sortfield) {
|
||||
|
@ -138,12 +136,13 @@ run_query (MuQuery *xapian, const gchar *query, MuConfig *opts, GError **err)
|
|||
if (opts->threads)
|
||||
qflags |= MU_QUERY_FLAG_THREADS;
|
||||
|
||||
iter = mu_query_run (xapian, query, sortid, opts->maxnum, qflags, err);
|
||||
iter = mu_query_run (xapian, query, sortid, opts->maxnum,
|
||||
(MuQueryFlags)qflags, err);
|
||||
return iter;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
exec_cmd (MuMsg *msg, MuMsgIter *iter, MuConfig *opts, GError **err)
|
||||
exec_cmd (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
||||
{
|
||||
gint status;
|
||||
char *cmdline, *escpath;
|
||||
|
@ -161,7 +160,7 @@ exec_cmd (MuMsg *msg, MuMsgIter *iter, MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
static gchar*
|
||||
resolve_bookmark (MuConfig *opts, GError **err)
|
||||
resolve_bookmark (const MuConfig *opts, GError **err)
|
||||
{
|
||||
MuBookmarks *bm;
|
||||
char* val;
|
||||
|
@ -187,7 +186,7 @@ resolve_bookmark (MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
static gchar*
|
||||
get_query (MuConfig *opts, GError **err)
|
||||
get_query (const MuConfig *opts, GError **err)
|
||||
{
|
||||
gchar *query, *bookmarkval;
|
||||
|
||||
|
@ -243,7 +242,7 @@ get_query_obj (MuStore *store, GError **err)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
prepare_links (MuConfig *opts, GError **err)
|
||||
prepare_links (const MuConfig *opts, GError **err)
|
||||
{
|
||||
/* note, mu_maildir_mkdir simply ignores whatever part of the
|
||||
* mail dir already exists */
|
||||
|
@ -266,7 +265,7 @@ prepare_links (MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
output_link (MuMsg *msg, MuMsgIter *iter, MuConfig *opts, GError **err)
|
||||
output_link (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
||||
{
|
||||
if (mu_msg_iter_is_first (iter) && !prepare_links (opts, err))
|
||||
return FALSE;
|
||||
|
@ -381,7 +380,7 @@ display_field (MuMsg *msg, MuMsgFieldId mfid)
|
|||
}
|
||||
|
||||
static void
|
||||
print_summary (MuMsg *msg, MuConfig *opts)
|
||||
print_summary (MuMsg *msg, const MuConfig *opts)
|
||||
{
|
||||
const char* body;
|
||||
char *summ;
|
||||
|
@ -472,7 +471,7 @@ output_plain_fields (MuMsg *msg, const char *fields,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
output_plain (MuMsg *msg, MuMsgIter *iter, MuConfig *opts, GError **err)
|
||||
output_plain (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
||||
{
|
||||
/* we reuse the color (whatever that may be)
|
||||
* for message-priority for threads, too */
|
||||
|
@ -489,7 +488,7 @@ output_plain (MuMsg *msg, MuMsgIter *iter, MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
output_sexp (MuMsg *msg, MuMsgIter *iter, MuConfig *opts, GError **err)
|
||||
output_sexp (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
||||
{
|
||||
char *sexp;
|
||||
const MuMsgIterThreadInfo *ti;
|
||||
|
@ -504,7 +503,7 @@ output_sexp (MuMsg *msg, MuMsgIter *iter, MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
output_json (MuMsg *msg, MuMsgIter *iter, MuConfig *opts, GError **err)
|
||||
output_json (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
||||
{
|
||||
#ifdef HAVE_JSON_GLIB
|
||||
JsonNode *node;
|
||||
|
@ -552,7 +551,7 @@ print_attr_xml (const char* elm, const char *str)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
output_xml (MuMsg *msg, MuMsgIter *iter, MuConfig *opts, GError **err)
|
||||
output_xml (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
||||
{
|
||||
if (mu_msg_iter_is_first(iter)) {
|
||||
g_print ("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
|
||||
|
@ -579,7 +578,7 @@ output_xml (MuMsg *msg, MuMsgIter *iter, MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
static OutputFunc*
|
||||
get_output_func (MuConfig *opts, GError **err)
|
||||
get_output_func (const MuConfig *opts, GError **err)
|
||||
{
|
||||
switch (opts->format) {
|
||||
case MU_CONFIG_FORMAT_LINKS: return output_link;
|
||||
|
@ -596,7 +595,7 @@ get_output_func (MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
output_query_results (MuMsgIter *iter, MuConfig *opts, GError **err)
|
||||
output_query_results (MuMsgIter *iter, const MuConfig *opts, GError **err)
|
||||
{
|
||||
int count;
|
||||
gboolean rv;
|
||||
|
@ -639,7 +638,7 @@ output_query_results (MuMsgIter *iter, MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
process_query (MuQuery *xapian, const gchar *query, MuConfig *opts, GError **err)
|
||||
process_query (MuQuery *xapian, const gchar *query, const MuConfig *opts, GError **err)
|
||||
{
|
||||
MuMsgIter *iter;
|
||||
gboolean rv;
|
||||
|
@ -655,7 +654,7 @@ process_query (MuQuery *xapian, const gchar *query, MuConfig *opts, GError **err
|
|||
}
|
||||
|
||||
static gboolean
|
||||
execute_find (MuStore *store, MuConfig *opts, GError **err)
|
||||
execute_find (MuStore *store, const MuConfig *opts, GError **err)
|
||||
{
|
||||
char *query_str;
|
||||
MuQuery *oracle;
|
||||
|
@ -686,7 +685,7 @@ execute_find (MuStore *store, MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
format_params_valid (MuConfig *opts, GError **err)
|
||||
format_params_valid (const MuConfig *opts, GError **err)
|
||||
{
|
||||
switch (opts->format) {
|
||||
case MU_CONFIG_FORMAT_EXEC:
|
||||
|
@ -727,7 +726,7 @@ format_params_valid (MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
query_params_valid (MuConfig *opts, GError **err)
|
||||
query_params_valid (const MuConfig *opts, GError **err)
|
||||
{
|
||||
const gchar *xpath;
|
||||
|
||||
|
@ -748,20 +747,22 @@ query_params_valid (MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
MuError
|
||||
mu_cmd_find (MuStore *store, MuConfig *opts, GError **err)
|
||||
mu_cmd_find (MuStore *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_FIND,
|
||||
MU_ERROR_INTERNAL);
|
||||
|
||||
if (opts->exec)
|
||||
opts->format = MU_CONFIG_FORMAT_EXEC; /* pseudo format */
|
||||
MuConfig myopts{*opts};
|
||||
|
||||
if (!query_params_valid (opts, err) ||
|
||||
!format_params_valid(opts, err))
|
||||
if (myopts.exec)
|
||||
myopts.format = MU_CONFIG_FORMAT_EXEC; /* pseudo format */
|
||||
|
||||
if (!query_params_valid (&myopts, err) ||
|
||||
!format_params_valid(&myopts, err))
|
||||
return MU_G_ERROR_CODE (err);
|
||||
|
||||
if (!execute_find (store, opts, err))
|
||||
if (!execute_find (store, &myopts, err))
|
||||
return MU_G_ERROR_CODE(err);
|
||||
else
|
||||
return MU_OK;
|
|
@ -17,11 +17,8 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
|
||||
#include "mu-cmd.h"
|
||||
#include "mu-cmd.hh"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
@ -70,7 +67,7 @@ install_sig_handler (void)
|
|||
|
||||
|
||||
static gboolean
|
||||
check_params (MuConfig *opts, GError **err)
|
||||
check_params (const MuConfig *opts, GError **err)
|
||||
{
|
||||
/* param[0] == 'index' there should be no param[1] */
|
||||
if (opts->params[1]) {
|
||||
|
@ -178,7 +175,7 @@ show_time (unsigned t, unsigned processed, gboolean color)
|
|||
}
|
||||
|
||||
static MuError
|
||||
cleanup_missing (MuIndex *midx, MuConfig *opts, MuIndexStats *stats,
|
||||
cleanup_missing (MuIndex *midx, const MuConfig *opts, MuIndexStats *stats,
|
||||
GError **err)
|
||||
{
|
||||
MuError rv;
|
||||
|
@ -213,7 +210,7 @@ cleanup_missing (MuIndex *midx, MuConfig *opts, MuIndexStats *stats,
|
|||
}
|
||||
|
||||
static MuError
|
||||
cmd_index (MuIndex *midx, MuConfig *opts, MuIndexStats *stats, GError **err)
|
||||
cmd_index (MuIndex *midx, const MuConfig *opts, MuIndexStats *stats, GError **err)
|
||||
{
|
||||
IndexData idata;
|
||||
MuError rv;
|
||||
|
@ -240,7 +237,7 @@ cmd_index (MuIndex *midx, MuConfig *opts, MuIndexStats *stats, GError **err)
|
|||
|
||||
|
||||
static MuIndex*
|
||||
init_mu_index (MuStore *store, MuConfig *opts, GError **err)
|
||||
init_mu_index (MuStore *store, const MuConfig *opts, GError **err)
|
||||
{
|
||||
MuIndex *midx;
|
||||
|
||||
|
@ -257,28 +254,26 @@ init_mu_index (MuStore *store, MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
MuError
|
||||
mu_cmd_index (MuStore *store, MuConfig *opts, GError **err)
|
||||
mu_cmd_index (Mu::Store& store, const MuConfig *opts, GError **err)
|
||||
{
|
||||
MuIndex *midx;
|
||||
MuIndexStats stats;
|
||||
gboolean rv;
|
||||
time_t t;
|
||||
|
||||
g_return_val_if_fail (opts, FALSE);
|
||||
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_INDEX,
|
||||
FALSE);
|
||||
g_return_val_if_fail (opts, MU_ERROR);
|
||||
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_INDEX, MU_ERROR);
|
||||
|
||||
/* create, and do error handling if needed */
|
||||
midx = init_mu_index (store, opts, err);
|
||||
midx = init_mu_index (reinterpret_cast<MuStore*>(&store), // ugh.
|
||||
opts, err);
|
||||
if (!midx)
|
||||
return MU_G_ERROR_CODE(err);
|
||||
throw Mu::Error(Mu::Error::Code::Internal, err/*consumes*/,
|
||||
"error in index");
|
||||
|
||||
mu_index_stats_clear (&stats);
|
||||
install_sig_handler ();
|
||||
|
||||
if (!opts->quiet)
|
||||
mu_store_print_info (store, opts->nocolor);
|
||||
|
||||
t = time (NULL);
|
||||
rv = cmd_index (midx, opts, &stats, err);
|
||||
|
||||
|
@ -297,5 +292,9 @@ mu_cmd_index (MuStore *store, MuConfig *opts, GError **err)
|
|||
|
||||
mu_index_destroy (midx);
|
||||
|
||||
return rv;
|
||||
if (rv != MU_OK)
|
||||
throw Mu::Error(Mu::Error::Code::Internal, err/*consumes*/,
|
||||
"error in index");
|
||||
|
||||
return rv ? MU_OK : MU_ERROR;
|
||||
}
|
|
@ -29,7 +29,7 @@
|
|||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "mu-cmd.h"
|
||||
#include "mu-cmd.hh"
|
||||
#include "mu-script.h"
|
||||
#include "mu-runtime.h"
|
||||
|
||||
|
@ -151,7 +151,7 @@ get_script_info_list (const char *muhome, GError **err)
|
|||
|
||||
|
||||
static gboolean
|
||||
check_params (MuConfig *opts, GError **err)
|
||||
check_params (const MuConfig *opts, GError **err)
|
||||
{
|
||||
if (!mu_util_supports (MU_FEATURE_GUILE)) {
|
||||
mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS,
|
||||
|
@ -165,7 +165,7 @@ check_params (MuConfig *opts, GError **err)
|
|||
|
||||
|
||||
MuError
|
||||
mu_cmd_script (MuConfig *opts, GError **err)
|
||||
mu_cmd_script (const MuConfig *opts, GError **err)
|
||||
{
|
||||
MuScriptInfo *msi;
|
||||
GSList *scripts;
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "mu-cmd.h"
|
||||
#include "mu-cmd.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
@ -29,7 +29,7 @@
|
|||
#include <glib/gprintf.h>
|
||||
|
||||
#include "mu-runtime.h"
|
||||
#include "mu-cmd.h"
|
||||
#include "mu-cmd.hh"
|
||||
#include "mu-maildir.h"
|
||||
#include "mu-query.h"
|
||||
#include "mu-index.h"
|
||||
|
@ -211,7 +211,7 @@ print_sexps (MuMsgIter *iter, unsigned maxnum)
|
|||
|
||||
struct Context {
|
||||
Context(){}
|
||||
Context (MuConfig *opts) {
|
||||
Context (const MuConfig *opts) {
|
||||
const auto dbpath{mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB)};
|
||||
GError *gerr{};
|
||||
store = mu_store_new_writable (dbpath, NULL);
|
||||
|
@ -314,86 +314,33 @@ add_handler (Context& context, const Parameters& params)
|
|||
}
|
||||
|
||||
|
||||
struct _PartInfo {
|
||||
GSList *attlist;
|
||||
MuMsgOptions opts;
|
||||
struct PartInfo {
|
||||
Node::Seq attseq;
|
||||
MuMsgOptions opts;
|
||||
};
|
||||
typedef struct _PartInfo PartInfo;
|
||||
|
||||
static void
|
||||
each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
|
||||
{
|
||||
char *att, *cachefile;
|
||||
|
||||
/* exclude things that don't look like proper attachments,
|
||||
* unless they're images */
|
||||
/* exclude things that don't look like proper attachments, unless they're images */
|
||||
if (!mu_msg_part_maybe_attachment(part))
|
||||
return;
|
||||
|
||||
GError *gerr{};
|
||||
cachefile = mu_msg_part_save_temp (msg,
|
||||
(MuMsgOptions)(pinfo->opts|MU_MSG_OPTION_OVERWRITE),
|
||||
part->index, &gerr);
|
||||
char *cachefile = mu_msg_part_save_temp (
|
||||
msg, (MuMsgOptions)(pinfo->opts|MU_MSG_OPTION_OVERWRITE),
|
||||
part->index, &gerr);
|
||||
if (!cachefile)
|
||||
throw Error (Error::Code::File, &gerr, "failed to save part");
|
||||
|
||||
att = g_strdup_printf ("(:file-name %s :mime-type \"%s/%s\")",
|
||||
quote(cachefile).c_str(), part->type, part->subtype);
|
||||
pinfo->attlist = g_slist_append (pinfo->attlist, att);
|
||||
Node::Seq seq;
|
||||
seq.add_prop(":file-name", cachefile);
|
||||
seq.add_prop(":mime-type", format("%s/%s", part->type, part->subtype));
|
||||
pinfo->attseq.add(std::move(seq));
|
||||
|
||||
g_free (cachefile);
|
||||
}
|
||||
|
||||
|
||||
/* take the attachments of msg, save them as tmp files, and return
|
||||
* as sexp (as a string) describing them
|
||||
*
|
||||
* ((:name <filename> :mime-type <mime-type> :disposition
|
||||
* <attachment|inline>) ... )
|
||||
*
|
||||
*/
|
||||
static gchar*
|
||||
include_attachments (MuMsg *msg, MuMsgOptions opts)
|
||||
{
|
||||
GSList *cur;
|
||||
GString *gstr;
|
||||
PartInfo pinfo;
|
||||
|
||||
pinfo.attlist = NULL;
|
||||
pinfo.opts = opts;
|
||||
mu_msg_part_foreach (msg, opts,
|
||||
(MuMsgPartForeachFunc)each_part,
|
||||
&pinfo);
|
||||
|
||||
gstr = g_string_sized_new (512);
|
||||
gstr = g_string_append_c (gstr, '(');
|
||||
for (cur = pinfo.attlist; cur; cur = g_slist_next (cur))
|
||||
g_string_append (gstr, (gchar*)cur->data);
|
||||
gstr = g_string_append_c (gstr, ')');
|
||||
|
||||
mu_str_free_list (pinfo.attlist);
|
||||
|
||||
return g_string_free (gstr, FALSE);
|
||||
}
|
||||
|
||||
enum { NEW, REPLY, FORWARD, EDIT, RESEND, INVALID_TYPE };
|
||||
static unsigned
|
||||
compose_type (const char *typestr)
|
||||
{
|
||||
if (g_str_equal (typestr, "reply"))
|
||||
return REPLY;
|
||||
else if (g_str_equal (typestr, "forward"))
|
||||
return FORWARD;
|
||||
else if (g_str_equal (typestr, "edit"))
|
||||
return EDIT;
|
||||
else if (g_str_equal (typestr, "resend"))
|
||||
return RESEND;
|
||||
else if (g_str_equal (typestr, "new"))
|
||||
return NEW;
|
||||
else
|
||||
return INVALID_TYPE;
|
||||
}
|
||||
|
||||
/* 'compose' produces the un-changed *original* message sexp (ie., the message
|
||||
* to reply to, forward or edit) for a new message to compose). It takes two
|
||||
* parameters: 'type' with the compose type (either reply, forward or
|
||||
|
@ -408,15 +355,15 @@ compose_type (const char *typestr)
|
|||
static void
|
||||
compose_handler (Context& context, const Parameters& params)
|
||||
{
|
||||
const auto typestr{get_symbol_or(params, "type")};
|
||||
const auto ctype{compose_type(typestr.c_str())};
|
||||
if (ctype == INVALID_TYPE)
|
||||
throw Error(Error::Code::InvalidArgument, "invalid compose type");
|
||||
auto ctype{get_symbol_or(params, "type")};
|
||||
|
||||
Node::Seq compose_seq;
|
||||
compose_seq.add_prop(":compose", ctype);
|
||||
|
||||
// message optioss below checks extract-images / extract-encrypted
|
||||
|
||||
char *sexp{}, *atts{};
|
||||
if (ctype == REPLY || ctype == FORWARD || ctype == EDIT || ctype == RESEND) {
|
||||
|
||||
if (ctype == "reply" || ctype == "forward" || ctype == "edit" || ctype == "resend") {
|
||||
|
||||
GError *gerr{};
|
||||
const unsigned docid{(unsigned)get_int_or(params, "docid")};
|
||||
|
@ -425,16 +372,22 @@ compose_handler (Context& context, const Parameters& params)
|
|||
throw Error{Error::Code::Store, &gerr, "failed to get message %u", docid};
|
||||
|
||||
const auto opts{message_options(params)};
|
||||
sexp = mu_msg_to_sexp (msg, docid, NULL, opts);
|
||||
atts = (ctype == FORWARD) ? include_attachments (msg, opts) : NULL;
|
||||
compose_seq.add_prop(":original", Mu::msg_to_sexp(msg, docid, {}, opts));
|
||||
|
||||
if (ctype == "forward") {
|
||||
PartInfo pinfo{};
|
||||
pinfo.opts = opts;
|
||||
mu_msg_part_foreach (msg, opts,
|
||||
(MuMsgPartForeachFunc)each_part, &pinfo);
|
||||
if (!pinfo.attseq.empty())
|
||||
compose_seq.add_prop (":include", std::move(pinfo.attseq));
|
||||
}
|
||||
mu_msg_unref (msg);
|
||||
}
|
||||
|
||||
print_expr ("(:compose %s :original %s :include %s)",
|
||||
typestr.c_str(), sexp ? sexp : "nil", atts ? atts : "nil");
|
||||
} else if (ctype != "new")
|
||||
throw Error(Error::Code::InvalidArgument, "invalid compose type");
|
||||
|
||||
g_free (sexp);
|
||||
g_free (atts);
|
||||
print_expr (std::move(compose_seq));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1318,7 +1271,7 @@ make_command_map (Context& context)
|
|||
}
|
||||
|
||||
MuError
|
||||
mu_cmd_server (MuConfig *opts, GError **err) try
|
||||
mu_cmd_server (const MuConfig *opts, GError **err) try
|
||||
{
|
||||
if (opts->commands) {
|
||||
Context ctx{};
|
||||
|
@ -1336,7 +1289,6 @@ mu_cmd_server (MuConfig *opts, GError **err) try
|
|||
return MU_OK;
|
||||
}
|
||||
|
||||
|
||||
const auto histpath{std::string{mu_runtime_path(MU_RUNTIME_PATH_CACHE)} + "/history"};
|
||||
setup_readline(histpath, 50);
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -27,7 +29,7 @@
|
|||
|
||||
#include "mu-msg.h"
|
||||
#include "mu-msg-part.h"
|
||||
#include "mu-cmd.h"
|
||||
#include "mu-cmd.hh"
|
||||
#include "mu-maildir.h"
|
||||
#include "mu-contacts.hh"
|
||||
#include "mu-runtime.h"
|
||||
|
@ -37,10 +39,12 @@
|
|||
#include "utils/mu-str.h"
|
||||
#include "utils/mu-date.h"
|
||||
|
||||
#include "utils/mu-error.hh"
|
||||
|
||||
#define VIEW_TERMINATOR '\f' /* form-feed */
|
||||
|
||||
static gboolean
|
||||
view_msg_sexp (MuMsg *msg, MuConfig *opts)
|
||||
view_msg_sexp (MuMsg *msg, const MuConfig *opts)
|
||||
{
|
||||
char *sexp;
|
||||
|
||||
|
@ -74,13 +78,12 @@ each_part (MuMsg *msg, MuMsgPart *part, gchar **attach)
|
|||
|
||||
/* return comma-sep'd list of attachments */
|
||||
static gchar *
|
||||
get_attach_str (MuMsg *msg, MuConfig *opts)
|
||||
get_attach_str (MuMsg *msg, const MuConfig *opts)
|
||||
{
|
||||
gchar *attach;
|
||||
MuMsgOptions msgopts;
|
||||
|
||||
msgopts = mu_config_get_msg_options(opts) |
|
||||
MU_MSG_OPTION_CONSOLE_PASSWORD;
|
||||
const auto msgopts = (MuMsgOptions)
|
||||
(mu_config_get_msg_options(opts) | MU_MSG_OPTION_CONSOLE_PASSWORD);
|
||||
|
||||
attach = NULL;
|
||||
mu_msg_part_foreach (msg, msgopts,
|
||||
|
@ -113,15 +116,15 @@ print_field (const char* field, const char *val, gboolean color)
|
|||
|
||||
/* a summary_len of 0 mean 'don't show summary, show body */
|
||||
static void
|
||||
body_or_summary (MuMsg *msg, MuConfig *opts)
|
||||
body_or_summary (MuMsg *msg, const MuConfig *opts)
|
||||
{
|
||||
const char *body;
|
||||
gboolean color;
|
||||
gboolean color;
|
||||
int my_opts = mu_config_get_msg_options(opts) |
|
||||
MU_MSG_OPTION_CONSOLE_PASSWORD;
|
||||
|
||||
color = !opts->nocolor;
|
||||
body = mu_msg_get_body_text (msg,
|
||||
mu_config_get_msg_options(opts) |
|
||||
MU_MSG_OPTION_CONSOLE_PASSWORD);
|
||||
body = mu_msg_get_body_text (msg, (MuMsgOptions)my_opts);
|
||||
if (!body) {
|
||||
if (mu_msg_get_flags (msg) & MU_FLAG_ENCRYPTED) {
|
||||
color_maybe (MU_COLOR_CYAN);
|
||||
|
@ -151,7 +154,7 @@ body_or_summary (MuMsg *msg, MuConfig *opts)
|
|||
/* we ignore fields for now */
|
||||
/* summary_len == 0 means "no summary */
|
||||
static gboolean
|
||||
view_msg_plain (MuMsg *msg, MuConfig *opts)
|
||||
view_msg_plain (MuMsg *msg, const MuConfig *opts)
|
||||
{
|
||||
gchar *attachs;
|
||||
time_t date;
|
||||
|
@ -189,7 +192,7 @@ view_msg_plain (MuMsg *msg, MuConfig *opts)
|
|||
|
||||
|
||||
static gboolean
|
||||
handle_msg (const char *fname, MuConfig *opts, GError **err)
|
||||
handle_msg (const char *fname, const MuConfig *opts, GError **err)
|
||||
{
|
||||
MuMsg *msg;
|
||||
gboolean rv;
|
||||
|
@ -216,7 +219,7 @@ handle_msg (const char *fname, MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
view_params_valid (MuConfig *opts, GError **err)
|
||||
view_params_valid (const MuConfig *opts, GError **err)
|
||||
{
|
||||
/* note: params[0] will be 'view' */
|
||||
if (!opts->params[0] || !opts->params[1]) {
|
||||
|
@ -240,7 +243,7 @@ view_params_valid (MuConfig *opts, GError **err)
|
|||
|
||||
|
||||
static MuError
|
||||
cmd_view (MuConfig *opts, GError **err)
|
||||
cmd_view (const MuConfig *opts, GError **err)
|
||||
{
|
||||
int i;
|
||||
gboolean rv;
|
||||
|
@ -266,13 +269,13 @@ cmd_view (MuConfig *opts, GError **err)
|
|||
|
||||
leave:
|
||||
if (!rv)
|
||||
return err && *err ? (*err)->code : MU_ERROR;
|
||||
return err && *err ? (MuError)(*err)->code : MU_ERROR;
|
||||
|
||||
return MU_OK;
|
||||
}
|
||||
|
||||
static MuError
|
||||
cmd_mkdir (MuConfig *opts, GError **err)
|
||||
cmd_mkdir (const MuConfig *opts, GError **err)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -289,7 +292,7 @@ cmd_mkdir (MuConfig *opts, GError **err)
|
|||
for (i = 1; opts->params[i]; ++i)
|
||||
if (!mu_maildir_mkdir (opts->params[i], opts->dirmode,
|
||||
FALSE, err))
|
||||
return err && *err ? (*err)->code :
|
||||
return err && *err ? (MuError)(*err)->code :
|
||||
MU_ERROR_FILE_CANNOT_MKDIR;
|
||||
return MU_OK;
|
||||
}
|
||||
|
@ -312,13 +315,10 @@ check_file_okay (const char *path, gboolean cmd_add)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
typedef gboolean (*ForeachMsgFunc) (MuStore *store, const char *path,
|
||||
GError **err);
|
||||
|
||||
typedef bool (*ForeachMsgFunc) (Mu::Store& store, const char *path, GError **err);
|
||||
|
||||
static MuError
|
||||
foreach_msg_file (MuStore *store, MuConfig *opts,
|
||||
foreach_msg_file (Mu::Store& store, const MuConfig *opts,
|
||||
ForeachMsgFunc foreach_func, GError **err)
|
||||
{
|
||||
unsigned u;
|
||||
|
@ -366,17 +366,19 @@ foreach_msg_file (MuStore *store, MuConfig *opts,
|
|||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
add_path_func (MuStore *store, const char *path, GError **err)
|
||||
static bool
|
||||
add_path_func (Mu::Store& store, const char *path, GError **err)
|
||||
{
|
||||
return mu_store_add_path (store, path, err);
|
||||
const auto docid = store.add_message (path);
|
||||
g_debug ("added message @ %s, docid=%u", docid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static MuError
|
||||
cmd_add (MuStore *store, MuConfig *opts, GError **err)
|
||||
cmd_add (Mu::Store& store, const MuConfig *opts, GError **err)
|
||||
{
|
||||
g_return_val_if_fail (store, MU_ERROR_INTERNAL);
|
||||
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
|
||||
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_ADD,
|
||||
MU_ERROR_INTERNAL);
|
||||
|
@ -384,20 +386,17 @@ cmd_add (MuStore *store, MuConfig *opts, GError **err)
|
|||
return foreach_msg_file (store, opts, add_path_func, err);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
remove_path_func (MuStore *store, const char *path, GError **err)
|
||||
static bool
|
||||
remove_path_func (Mu::Store& store, const char *path, GError **err)
|
||||
{
|
||||
if (!mu_store_remove_path (store, path)) {
|
||||
mu_util_g_set_error (err, MU_ERROR_XAPIAN_REMOVE_FAILED,
|
||||
"failed to remove %s", path);
|
||||
return FALSE;
|
||||
}
|
||||
const auto res = store.remove_message (path);
|
||||
g_debug ("removed %s (%s)", path, res ? "yes" : "no");
|
||||
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static MuError
|
||||
cmd_remove (MuStore *store, MuConfig *opts, GError **err)
|
||||
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,
|
||||
|
@ -406,25 +405,23 @@ cmd_remove (MuStore *store, MuConfig *opts, GError **err)
|
|||
return foreach_msg_file (store, opts, remove_path_func, err);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tickle_func (MuStore *store, const char *path, GError **err)
|
||||
static bool
|
||||
tickle_func (Mu::Store& store, const char *path, GError **err)
|
||||
{
|
||||
MuMsg *msg;
|
||||
gboolean rv;
|
||||
|
||||
msg = mu_msg_new_from_file (path, NULL, err);
|
||||
MuMsg *msg{mu_msg_new_from_file (path, NULL, err)};
|
||||
if (!msg)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
rv = mu_msg_tickle (msg, err);
|
||||
const auto res = mu_msg_tickle (msg, err);
|
||||
g_debug ("tickled %s (%s)", res ? "ok" : "failed");
|
||||
mu_msg_unref (msg);
|
||||
|
||||
return rv;
|
||||
return res == TRUE;
|
||||
}
|
||||
|
||||
|
||||
static MuError
|
||||
cmd_tickle (MuStore *store, MuConfig *opts, GError **err)
|
||||
cmd_tickle (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_TICKLE,
|
||||
|
@ -509,11 +506,11 @@ print_verdict (VData *vdata, gboolean color, gboolean verbose)
|
|||
|
||||
|
||||
static MuError
|
||||
cmd_verify (MuConfig *opts, GError **err)
|
||||
cmd_verify (const MuConfig *opts, GError **err)
|
||||
{
|
||||
MuMsg *msg;
|
||||
MuMsgOptions msgopts;
|
||||
VData vdata;
|
||||
int msgopts;
|
||||
VData vdata;
|
||||
|
||||
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
|
||||
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_VERIFY,
|
||||
|
@ -537,7 +534,7 @@ cmd_verify (MuConfig *opts, GError **err)
|
|||
vdata.combined_status = MU_MSG_PART_SIG_STATUS_UNSIGNED;
|
||||
vdata.oneline = FALSE;
|
||||
|
||||
mu_msg_part_foreach (msg, msgopts,
|
||||
mu_msg_part_foreach (msg, (MuMsgOptions)msgopts,
|
||||
(MuMsgPartForeachFunc)each_sig, &vdata);
|
||||
|
||||
if (!opts->quiet)
|
||||
|
@ -551,20 +548,51 @@ cmd_verify (MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
static MuError
|
||||
cmd_info (MuStore *store, MuConfig *opts, GError **err)
|
||||
cmd_info (const Mu::Store& store, const MuConfig *opts, GError **err)
|
||||
{
|
||||
mu_store_print_info (store, opts->nocolor);
|
||||
const auto green{opts->nocolor ? "" : MU_COLOR_GREEN};
|
||||
const auto def{opts->nocolor ? "" : MU_COLOR_DEFAULT};
|
||||
|
||||
std::cout << "database-path : "
|
||||
<< green << store.database_path() << def << "\n"
|
||||
<< "messages in store : "
|
||||
<< green << store.size() << def << "\n"
|
||||
<< "schema-version : "
|
||||
<< green << store.schema_version() << def << "\n";
|
||||
|
||||
const auto created{store.created()};
|
||||
const auto tstamp{::localtime (&created)};
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat-y2k"
|
||||
char tbuf[64];
|
||||
strftime (tbuf, sizeof(tbuf), "%c", tstamp);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
std::cout << "created : " << green << tbuf << def << "\n"
|
||||
<< "maildir : "
|
||||
<< green << store.root_maildir() << def << "\n";
|
||||
|
||||
std::cout << ("personal-addresses : ");
|
||||
|
||||
const auto addrs{store.personal_addresses()};
|
||||
if (addrs.empty())
|
||||
std::cout << green << "<none>" << def << "\n";
|
||||
else {
|
||||
bool first{true};
|
||||
for (auto&& c: addrs) {
|
||||
std::cout << (!first ? " " : "")
|
||||
<< green << c << def << "\n";
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
return MU_OK;
|
||||
}
|
||||
|
||||
|
||||
static MuError
|
||||
cmd_init (MuConfig *opts, GError **err)
|
||||
cmd_init (const MuConfig *opts, GError **err)
|
||||
{
|
||||
MuStore *store;
|
||||
const char *path;
|
||||
|
||||
/* not provided, nor could we find a good default */
|
||||
if (!opts->maildir) {
|
||||
mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS,
|
||||
|
@ -573,26 +601,43 @@ cmd_init (MuConfig *opts, GError **err)
|
|||
return MU_ERROR_IN_PARAMETERS;
|
||||
}
|
||||
|
||||
path = mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB);
|
||||
store = mu_store_new_create (path,
|
||||
opts->maildir,
|
||||
(const char**)opts->my_addresses,
|
||||
err);
|
||||
if (!store)
|
||||
return MU_G_ERROR_CODE(err);
|
||||
Mu::StringVec my_addrs;
|
||||
auto addrs = opts->my_addresses;
|
||||
while (addrs && *addrs) {
|
||||
my_addrs.emplace_back (*addrs);
|
||||
++addrs;
|
||||
}
|
||||
|
||||
Mu::Store store(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB), opts->maildir, my_addrs);
|
||||
|
||||
if (!opts->quiet) {
|
||||
mu_store_print_info (store, opts->nocolor);
|
||||
cmd_info (store, opts, NULL);
|
||||
g_print ("\nstore created.\n"
|
||||
"use 'mu index' to fill the database "
|
||||
"with your messages.\n"
|
||||
"see mu-index(1) for details\n");
|
||||
}
|
||||
|
||||
mu_store_unref (store);
|
||||
return MU_OK;
|
||||
}
|
||||
|
||||
static MuError
|
||||
cmd_index (Mu::Store& store, const MuConfig *opts, GError **err)
|
||||
{
|
||||
const auto res = mu_cmd_index(store, opts, err);
|
||||
if (res == MU_OK && !opts->quiet)
|
||||
cmd_info(store, opts, err);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static MuError
|
||||
cmd_find (const MuConfig *opts, GError **err)
|
||||
{
|
||||
Mu::Store store{mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB), true/*readonly*/};
|
||||
|
||||
return mu_cmd_find(reinterpret_cast<MuStore*>(&store), opts, err);
|
||||
}
|
||||
|
||||
static void
|
||||
show_usage (void)
|
||||
|
@ -604,46 +649,27 @@ show_usage (void)
|
|||
"more information\n");
|
||||
}
|
||||
|
||||
typedef MuError (*store_func) (MuStore *, MuConfig *, GError **err);
|
||||
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
|
||||
with_store (store_func func, MuConfig *opts, gboolean read_only, GError **err)
|
||||
with_readonly_store (readonly_store_func func, const MuConfig *opts, GError **err)
|
||||
{
|
||||
MuError merr;
|
||||
MuStore *store;
|
||||
const char *path;
|
||||
|
||||
path = mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB);
|
||||
|
||||
if (read_only)
|
||||
store = mu_store_new_readable (path, err);
|
||||
else
|
||||
store = mu_store_new_writable (path, err);
|
||||
|
||||
if (!store)
|
||||
return MU_G_ERROR_CODE(err);
|
||||
|
||||
merr = func (store, opts, err);
|
||||
mu_store_unref (store);
|
||||
|
||||
return merr;
|
||||
const Mu::Store store{mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB), true/*readonly*/};
|
||||
return func (store, opts, err);
|
||||
}
|
||||
|
||||
static MuError
|
||||
with_readonly_store (store_func func, MuConfig *opts, GError **err)
|
||||
with_writable_store (writable_store_func func, const MuConfig *opts, GError **err)
|
||||
{
|
||||
return with_store (func, opts, TRUE, err);
|
||||
Mu::Store store{mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB), false/*!readonly*/};
|
||||
return func (store, opts, err);
|
||||
}
|
||||
|
||||
static MuError
|
||||
with_writable_store (store_func func, MuConfig *opts, GError **err)
|
||||
{
|
||||
return with_store (func, opts, FALSE, err);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_params (MuConfig *opts, GError **err)
|
||||
check_params (const MuConfig *opts, GError **err)
|
||||
{
|
||||
if (!opts->params||!opts->params[0]) {/* no command? */
|
||||
show_usage ();
|
||||
|
@ -656,7 +682,7 @@ check_params (MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
MuError
|
||||
mu_cmd_execute (MuConfig *opts, GError **err)
|
||||
mu_cmd_execute (const MuConfig *opts, GError **err) try
|
||||
{
|
||||
MuError merr;
|
||||
|
||||
|
@ -683,9 +709,9 @@ mu_cmd_execute (MuConfig *opts, GError **err)
|
|||
case MU_CONFIG_CMD_CFIND:
|
||||
merr = with_readonly_store (mu_cmd_cfind, opts, err); break;
|
||||
case MU_CONFIG_CMD_FIND:
|
||||
merr = with_readonly_store (mu_cmd_find, opts, err); break;
|
||||
merr = cmd_find(opts, err); break;
|
||||
case MU_CONFIG_CMD_INFO:
|
||||
merr = with_readonly_store (cmd_info, opts, err); break;
|
||||
merr = with_readonly_store (cmd_info, opts, err); break;
|
||||
|
||||
/* writable store */
|
||||
|
||||
|
@ -696,7 +722,7 @@ mu_cmd_execute (MuConfig *opts, GError **err)
|
|||
case MU_CONFIG_CMD_TICKLE:
|
||||
merr = with_writable_store (cmd_tickle, opts, err); break;
|
||||
case MU_CONFIG_CMD_INDEX:
|
||||
merr = with_writable_store (mu_cmd_index, opts, err); break;
|
||||
merr = with_writable_store (cmd_index, opts, err); break;
|
||||
|
||||
/* commands instantiate store themselves */
|
||||
case MU_CONFIG_CMD_INIT:
|
||||
|
@ -709,4 +735,11 @@ mu_cmd_execute (MuConfig *opts, GError **err)
|
|||
}
|
||||
|
||||
return merr;
|
||||
|
||||
} catch (const Mu::Error& er) {
|
||||
g_set_error(err, MU_ERROR_DOMAIN, MU_ERROR, "%s", er.what());
|
||||
return MU_ERROR;
|
||||
} catch (...) {
|
||||
g_set_error(err, MU_ERROR_DOMAIN, MU_ERROR, "%s", "caught exception");
|
||||
return MU_ERROR;
|
||||
}
|
|
@ -21,7 +21,7 @@
|
|||
#define __MU_CMD_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <mu-config.h>
|
||||
#include <mu-config.hh>
|
||||
#include <mu-store.hh>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
@ -37,8 +37,8 @@ G_BEGIN_DECLS
|
|||
* >MU_OK (0) results, MU_EXITCODE_NO_MATCHES if the command
|
||||
* succeeds but there no matches, some error code for all other errors
|
||||
*/
|
||||
MuError mu_cmd_find (MuStore *store, MuConfig *opts, GError **err);
|
||||
|
||||
MuError mu_cmd_find (MuStore* store, const MuConfig *opts,
|
||||
GError **err);
|
||||
|
||||
/**
|
||||
* execute the 'extract' command
|
||||
|
@ -49,7 +49,7 @@ MuError mu_cmd_find (MuStore *store, MuConfig *opts, GError **err);
|
|||
* @return MU_OK (0) if the command succeeds,
|
||||
* some error code otherwise
|
||||
*/
|
||||
MuError mu_cmd_extract (MuConfig *opts, GError **err);
|
||||
MuError mu_cmd_extract (const MuConfig *opts, GError **err);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -61,7 +61,7 @@ MuError mu_cmd_extract (MuConfig *opts, GError **err);
|
|||
* @return MU_OK (0) if the command succeeds,
|
||||
* some error code otherwise
|
||||
*/
|
||||
MuError mu_cmd_script (MuConfig *opts, GError **err);
|
||||
MuError mu_cmd_script (const MuConfig *opts, GError **err);
|
||||
|
||||
/**
|
||||
* execute the cfind command
|
||||
|
@ -73,7 +73,8 @@ MuError mu_cmd_script (MuConfig *opts, GError **err);
|
|||
* @return MU_OK (0) if the command succeeds,
|
||||
* some error code otherwise
|
||||
*/
|
||||
MuError mu_cmd_cfind (MuStore *store, MuConfig *opts, GError **err);
|
||||
MuError mu_cmd_cfind (const Mu::Store& store, const MuConfig *opts,
|
||||
GError **err);
|
||||
|
||||
/**
|
||||
* execute some mu command, based on 'opts'
|
||||
|
@ -83,7 +84,7 @@ MuError mu_cmd_cfind (MuStore *store, MuConfig *opts, GError **err);
|
|||
*
|
||||
* @return MU_OK if all went wall, some error code otherwise
|
||||
*/
|
||||
MuError mu_cmd_execute (MuConfig *opts, GError **err);
|
||||
MuError mu_cmd_execute (const MuConfig *opts, GError **err);
|
||||
|
||||
/**
|
||||
* execute the 'index' command
|
||||
|
@ -95,7 +96,7 @@ MuError mu_cmd_execute (MuConfig *opts, GError **err);
|
|||
* @return MU_OK (0) if the command succeeded,
|
||||
* some error code otherwise
|
||||
*/
|
||||
MuError mu_cmd_index (MuStore *store, MuConfig *opt, GError **err);
|
||||
MuError mu_cmd_index (Mu::Store& store, const MuConfig *opt, GError **err);
|
||||
|
||||
/**
|
||||
* execute the server command
|
||||
|
@ -104,7 +105,7 @@ MuError mu_cmd_index (MuStore *store, MuConfig *opt, GError **err);
|
|||
*
|
||||
* @return MU_OK (0) if the command succeeds, some error code otherwise
|
||||
*/
|
||||
MuError mu_cmd_server (MuConfig *opts, GError **err);
|
||||
MuError mu_cmd_server (const MuConfig *opts, GError **err);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
@ -24,8 +24,9 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mu-config.h"
|
||||
#include "mu-cmd.h"
|
||||
#include "mu-config.hh"
|
||||
#include "mu-cmd.hh"
|
||||
#include "mu-msg.h"
|
||||
|
||||
|
||||
static MuConfig MU_CONFIG;
|
||||
|
@ -115,7 +116,7 @@ config_options_group_mu (void)
|
|||
|
||||
{G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY,
|
||||
&MU_CONFIG.params, "parameters", NULL},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
{NULL, 0, 0, (GOptionArg)0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
og = g_option_group_new("mu", "general mu options", "", NULL, NULL);
|
||||
|
@ -143,7 +144,7 @@ config_options_group_init (void)
|
|||
{"my-address", 0, 0, G_OPTION_ARG_STRING_ARRAY,
|
||||
&MU_CONFIG.my_addresses, "my e-mail address; can be used multiple times",
|
||||
"<address>"},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
og = g_option_group_new("init", "Options for the 'index' command",
|
||||
|
@ -186,7 +187,7 @@ config_options_group_index (void)
|
|||
"only check dir-timestamps (false)", NULL},
|
||||
{"nocleanup", 0, 0, G_OPTION_ARG_NONE, &MU_CONFIG.nocleanup,
|
||||
"don't clean up the database after indexing (false)", NULL},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
og = g_option_group_new("index", "Options for the 'index' command",
|
||||
|
@ -257,7 +258,7 @@ config_options_group_find (void)
|
|||
{"after", 0, 0, G_OPTION_ARG_INT, &MU_CONFIG.after,
|
||||
"only show messages whose m_time > T (t_time)",
|
||||
"<timestamp>"},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
og = g_option_group_new("find",
|
||||
|
@ -275,7 +276,7 @@ config_options_group_mkdir (void)
|
|||
GOptionEntry entries[] = {
|
||||
{"mode", 0, 0, G_OPTION_ARG_INT, &MU_CONFIG.dirmode,
|
||||
"set the mode (as in chmod), in octal notation", "<mode>"},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
/* set dirmode before, because '0000' is a valid mode */
|
||||
|
@ -309,7 +310,7 @@ config_options_group_cfind (void)
|
|||
"whether to only get 'personal' contacts", NULL},
|
||||
{"after", 0, 0, G_OPTION_ARG_INT, &MU_CONFIG.after,
|
||||
"only get addresses last seen after T", "<timestamp>"},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
og = g_option_group_new("cfind", "Options for the 'cfind' command",
|
||||
|
@ -326,7 +327,7 @@ config_options_group_script (void)
|
|||
GOptionEntry entries[] = {
|
||||
{G_OPTION_REMAINING, 0,0, G_OPTION_ARG_STRING_ARRAY,
|
||||
&MU_CONFIG.params, "script parameters", NULL},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
og = g_option_group_new("script", "Options for the 'script' command",
|
||||
|
@ -359,7 +360,7 @@ crypto_option_entries (void)
|
|||
"attempt to use the GPG agent (false)", NULL},
|
||||
{"decrypt", 0, 0, G_OPTION_ARG_NONE, &MU_CONFIG.decrypt,
|
||||
"attempt to decrypt the message", NULL},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
return entries;
|
||||
|
@ -378,7 +379,7 @@ config_options_group_view (void)
|
|||
"<term>"},
|
||||
{"format", 'o', 0, G_OPTION_ARG_STRING, &MU_CONFIG.formatstr,
|
||||
"output format ('plain'(*), 'sexp')", "<format>"},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
og = g_option_group_new("view", "Options for the 'view' command",
|
||||
|
@ -419,7 +420,7 @@ config_options_group_extract (void)
|
|||
"overwrite existing files (false)", NULL},
|
||||
{"play", 0, 0, G_OPTION_ARG_NONE, &MU_CONFIG.play,
|
||||
"try to 'play' (open) the extracted parts", NULL},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
|
||||
};
|
||||
og = g_option_group_new("extract",
|
||||
"Options for the 'extract' command",
|
||||
|
@ -453,7 +454,7 @@ config_options_group_server (void)
|
|||
"list the available command and their parameters, then exit", NULL},
|
||||
{"eval", 'e', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING,
|
||||
&MU_CONFIG.eval, "expression to evaluate", "<expr>"},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
og = g_option_group_new("server",
|
||||
|
@ -587,7 +588,7 @@ massage_help (const char *help)
|
|||
char *str;
|
||||
|
||||
rx = g_regex_new ("^Usage:.*\n.*\n",
|
||||
0, G_REGEX_MATCH_NEWLINE_ANY, NULL);
|
||||
(GRegexCompileFlags)0, G_REGEX_MATCH_NEWLINE_ANY, NULL);
|
||||
str = g_regex_replace (rx, help,
|
||||
-1, 0, "",
|
||||
G_REGEX_MATCH_NEWLINE_ANY, NULL);
|
||||
|
@ -774,7 +775,7 @@ mu_config_uninit (MuConfig *opts)
|
|||
}
|
||||
|
||||
size_t
|
||||
mu_config_param_num (MuConfig *opts)
|
||||
mu_config_param_num (const MuConfig *opts)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
|
@ -786,9 +787,9 @@ mu_config_param_num (MuConfig *opts)
|
|||
|
||||
|
||||
MuMsgOptions
|
||||
mu_config_get_msg_options (MuConfig *muopts)
|
||||
mu_config_get_msg_options (const MuConfig *muopts)
|
||||
{
|
||||
MuMsgOptions opts;
|
||||
int opts;
|
||||
|
||||
opts = MU_MSG_OPTION_NONE;
|
||||
|
||||
|
@ -803,5 +804,5 @@ mu_config_get_msg_options (MuConfig *muopts)
|
|||
if (muopts->overwrite)
|
||||
opts |= MU_MSG_OPTION_OVERWRITE;
|
||||
|
||||
return opts;
|
||||
return (MuMsgOptions)opts;
|
||||
}
|
|
@ -226,7 +226,7 @@ void mu_config_uninit (MuConfig *conf);
|
|||
* the exit code of the process
|
||||
*
|
||||
*/
|
||||
MuError mu_config_execute (MuConfig *conf);
|
||||
MuError mu_config_execute (const MuConfig *conf);
|
||||
|
||||
/**
|
||||
* count the number of non-option parameters
|
||||
|
@ -235,7 +235,7 @@ MuError mu_config_execute (MuConfig *conf);
|
|||
*
|
||||
* @return the number of non-option parameters, or 0 in case of error
|
||||
*/
|
||||
size_t mu_config_param_num (MuConfig *conf);
|
||||
size_t mu_config_param_num (const MuConfig *conf);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -245,7 +245,7 @@ size_t mu_config_param_num (MuConfig *conf);
|
|||
*
|
||||
* @return the corresponding MuMsgOptions
|
||||
*/
|
||||
MuMsgOptions mu_config_get_msg_options (MuConfig *opts);
|
||||
MuMsgOptions mu_config_get_msg_options (const MuConfig *opts);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -253,7 +253,7 @@ MuMsgOptions mu_config_get_msg_options (MuConfig *opts);
|
|||
*
|
||||
* @param cmd the command to show help for
|
||||
*/
|
||||
void mu_config_show_help (MuConfigCmd cmd);
|
||||
void mu_config_show_help (const MuConfigCmd cmd);
|
||||
|
||||
G_END_DECLS
|
||||
|
6
mu/mu.cc
6
mu/mu.cc
|
@ -17,16 +17,14 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include "mu-config.h"
|
||||
#include "mu-cmd.h"
|
||||
#include "mu-config.hh"
|
||||
#include "mu-cmd.hh"
|
||||
#include "mu-runtime.h"
|
||||
|
||||
|
||||
|
|
|
@ -226,11 +226,14 @@ test_mu_cfind_mutt_ab (void)
|
|||
"'testmu\\.xxx?'",
|
||||
MU_PROGRAM, CONTACTS_CACHE);
|
||||
|
||||
if (g_test_verbose())
|
||||
g_print("%s\n", cmdline);
|
||||
|
||||
output = erroutput = NULL;
|
||||
g_assert (g_spawn_command_line_sync (cmdline, &output, &erroutput,
|
||||
NULL, NULL));
|
||||
|
||||
g_assert (output);
|
||||
|
||||
if (output[39] == 'h')
|
||||
g_assert_cmpstr (output,
|
||||
==,
|
||||
|
@ -305,20 +308,26 @@ test_mu_cfind_csv (void)
|
|||
"'testmu\\.xxx?'",
|
||||
MU_PROGRAM, CONTACTS_CACHE);
|
||||
|
||||
if (g_test_verbose())
|
||||
g_print("%s\n", cmdline);
|
||||
|
||||
output = erroutput = NULL;
|
||||
g_assert (g_spawn_command_line_sync (cmdline, &output, &erroutput,
|
||||
NULL, NULL));
|
||||
|
||||
g_print ("\n\n%s\n\n", output);
|
||||
|
||||
g_assert (output);
|
||||
if (output[0] == 'H')
|
||||
if (output[1] == 'H')
|
||||
g_assert_cmpstr (output,
|
||||
==,
|
||||
"Helmut Kröger,hk@testmu.xxx\n"
|
||||
"Mü,testmu@testmu.xx\n");
|
||||
"\"Helmut Kröger\",\"hk@testmu.xxx\"\n"
|
||||
"\"Mü\",\"testmu@testmu.xx\"\n");
|
||||
else
|
||||
g_assert_cmpstr (output,
|
||||
==,
|
||||
"Mü,testmu@testmu.xx\n"
|
||||
"Helmut Kröger,hk@testmu.xxx\n");
|
||||
"\"Mü\",\"testmu@testmu.xx\"\n"
|
||||
"\"Helmut Kröger\",\"hk@testmu.xxx\"\n");
|
||||
g_free (cmdline);
|
||||
g_free (output);
|
||||
g_free (erroutput);
|
||||
|
@ -349,8 +358,9 @@ main (int argc, char *argv[])
|
|||
test_mu_cfind_csv);
|
||||
|
||||
g_log_set_handler (NULL,
|
||||
(GLogLevelFlags)(
|
||||
G_LOG_LEVEL_MASK | G_LOG_LEVEL_WARNING|
|
||||
G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION,
|
||||
G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION),
|
||||
(GLogFunc)black_hole, NULL);
|
||||
|
||||
rv = g_test_run ();
|
|
@ -900,8 +900,9 @@ main (int argc, char *argv[])
|
|||
g_test_add_func ("/mu-cmd/test-mu-verify-bad", test_mu_verify_bad);
|
||||
|
||||
g_log_set_handler (NULL,
|
||||
(GLogLevelFlags)(
|
||||
G_LOG_LEVEL_MASK | G_LOG_LEVEL_WARNING|
|
||||
G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION,
|
||||
G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION),
|
||||
(GLogFunc)black_hole, NULL);
|
||||
|
||||
DBPATH = fill_database ();
|
|
@ -754,8 +754,8 @@ main (int argc, char *argv[])
|
|||
|
||||
if (!g_test_verbose())
|
||||
g_log_set_handler (NULL,
|
||||
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL|
|
||||
G_LOG_FLAG_RECURSION,
|
||||
(GLogLevelFlags)(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL|
|
||||
G_LOG_FLAG_RECURSION),
|
||||
(GLogFunc)black_hole, NULL);
|
||||
|
||||
rv = g_test_run ();
|
|
@ -124,9 +124,10 @@ static MuMsgIter*
|
|||
run_and_get_iter_full (const char *xpath, const char *query,
|
||||
MuMsgFieldId sort_field, MuQueryFlags flags)
|
||||
{
|
||||
MuQuery *mquery;
|
||||
MuStore *store;
|
||||
MuMsgIter *iter;
|
||||
MuQuery *mquery;
|
||||
MuStore *store;
|
||||
MuMsgIter *iter;
|
||||
int myflags;
|
||||
|
||||
store = mu_store_new_readable (xpath, NULL);
|
||||
g_assert (store);
|
||||
|
@ -135,8 +136,10 @@ run_and_get_iter_full (const char *xpath, const char *query,
|
|||
mu_store_unref (store);
|
||||
g_assert (query);
|
||||
|
||||
flags |= MU_QUERY_FLAG_THREADS;
|
||||
iter = mu_query_run (mquery, query, sort_field, -1, flags, NULL);
|
||||
myflags = flags;
|
||||
myflags |= MU_QUERY_FLAG_THREADS;
|
||||
iter = mu_query_run (mquery, query, sort_field, -1,
|
||||
(MuQueryFlags)myflags, NULL);
|
||||
mu_query_destroy (mquery);
|
||||
g_assert (iter);
|
||||
|
||||
|
@ -233,7 +236,7 @@ query_testdir (const char *query, MuMsgFieldId sort_field, gboolean descending)
|
|||
{
|
||||
MuMsgIter *iter;
|
||||
gchar *xpath;
|
||||
MuQueryFlags flags;
|
||||
int flags;
|
||||
|
||||
flags = MU_QUERY_FLAG_NONE;
|
||||
if (descending)
|
||||
|
@ -242,7 +245,7 @@ query_testdir (const char *query, MuMsgFieldId sort_field, gboolean descending)
|
|||
xpath = fill_database (MU_TESTMAILDIR3);
|
||||
g_assert (xpath != NULL);
|
||||
|
||||
iter = run_and_get_iter_full (xpath, query, sort_field, flags);
|
||||
iter = run_and_get_iter_full (xpath, query, sort_field, (MuQueryFlags)flags);
|
||||
g_assert (iter != NULL);
|
||||
g_assert (!mu_msg_iter_is_done (iter));
|
||||
|
||||
|
@ -453,7 +456,8 @@ main (int argc, char *argv[])
|
|||
test_mu_threads_sort_granchild_promotes_only_subthread);
|
||||
|
||||
g_log_set_handler (NULL,
|
||||
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION,
|
||||
(GLogLevelFlags)(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL|
|
||||
G_LOG_FLAG_RECURSION),
|
||||
(GLogFunc)black_hole, NULL);
|
||||
|
||||
rv = g_test_run ();
|
Loading…
Reference in New Issue