* minor changes, trailing whitespace fixes

This commit is contained in:
Dirk-Jan C. Binnema
2011-08-29 23:38:55 +03:00
parent 93ec32dcbf
commit fbc786f2fc
10 changed files with 528 additions and 506 deletions

View File

@ -64,22 +64,22 @@ upgrade_warning (void)
MU_XAPIAN_DB_VERSION);
g_message ("please run 'mu index --rebuild' (see the man page)");
}
static gboolean
print_xapian_query (MuQuery *xapian, const gchar *query, size_t *count)
{
char *querystr;
GError *err;
err = NULL;
querystr = mu_query_as_string (xapian, query, &err);
if (!querystr) {
g_warning ("error: %s", err->message);
g_error_free (err);
return FALSE;
}
}
g_print ("%s\n", querystr);
g_free (querystr);
@ -93,14 +93,14 @@ static MuMsgFieldId
sort_field_from_string (const char* fieldstr)
{
MuMsgFieldId mfid;
mfid = mu_msg_field_id_from_name (fieldstr, FALSE);
/* not found? try a shortcut */
if (mfid == MU_MSG_FIELD_ID_NONE &&
strlen(fieldstr) == 1)
mfid = mu_msg_field_id_from_shortcut(fieldstr[0],
FALSE);
FALSE);
if (mfid == MU_MSG_FIELD_ID_NONE)
g_warning ("not a valid sort field: '%s'\n",
fieldstr);
@ -115,7 +115,7 @@ output_query_results (MuMsgIter *iter, MuConfig *opts, size_t *count)
case MU_CONFIG_FORMAT_LINKS:
return output_links (iter, opts->linksdir, opts->clearlinks,
count);
case MU_CONFIG_FORMAT_PLAIN:
case MU_CONFIG_FORMAT_PLAIN:
return output_plain (iter, opts->fields, opts->summary,
opts->threads, opts->color,
opts->include_unreadable,
@ -124,7 +124,7 @@ output_query_results (MuMsgIter *iter, MuConfig *opts, size_t *count)
return output_xml (iter, opts->include_unreadable, count);
case MU_CONFIG_FORMAT_SEXP:
return output_sexp (iter, opts->threads,
opts->include_unreadable, count);
opts->include_unreadable, count);
default:
g_assert_not_reached ();
return FALSE;
@ -138,7 +138,7 @@ run_query (MuQuery *xapian, const gchar *query, MuConfig *opts, size_t *count)
GError *err;
MuMsgIter *iter;
MuMsgFieldId sortid;
sortid = MU_MSG_FIELD_ID_NONE;
if (opts->sortfield) {
sortid = sort_field_from_string (opts->sortfield);
@ -147,7 +147,7 @@ run_query (MuQuery *xapian, const gchar *query, MuConfig *opts, size_t *count)
}
err = NULL;
iter = mu_query_run (xapian, query, opts->threads, sortid,
iter = mu_query_run (xapian, query, opts->threads, sortid,
opts->descending ? FALSE : TRUE,
&err);
if (!iter) {
@ -158,7 +158,7 @@ run_query (MuQuery *xapian, const gchar *query, MuConfig *opts, size_t *count)
return iter;
}
static gboolean
process_query (MuQuery *xapian, const gchar *query, MuConfig *opts,
@ -166,16 +166,16 @@ process_query (MuQuery *xapian, const gchar *query, MuConfig *opts,
{
MuMsgIter *iter;
gboolean rv;
iter = run_query (xapian, query, opts, count);
if (!iter)
return FALSE;
rv = output_query_results (iter, opts, count);
if (rv && count && *count == 0)
g_warning ("no matching messages found");
mu_msg_iter_destroy (iter);
return rv;
@ -189,14 +189,14 @@ exec_cmd (const char *path, const char *cmd)
GError *err;
char *cmdline, *escpath;
gboolean rv;
if (access (path, R_OK) != 0) {
g_warning ("cannot read %s: %s", path, strerror(errno));
return FALSE;
}
escpath = g_strescape (path, NULL);
cmdline = g_strdup_printf ("%s %s", cmd, escpath);
err = NULL;
rv = g_spawn_command_line_sync (cmdline, NULL, NULL,
@ -221,7 +221,7 @@ exec_cmd_on_query (MuQuery *xapian, const gchar *query, MuConfig *opts,
{
MuMsgIter *iter;
gboolean rv;
if (!(iter = run_query (xapian, query, opts, count)))
return FALSE;
@ -232,10 +232,10 @@ exec_cmd_on_query (MuQuery *xapian, const gchar *query, MuConfig *opts,
if (rv)
++*count;
}
if (rv && count && *count == 0)
g_warning ("no matching messages found");
mu_msg_iter_destroy (iter);
return rv;
@ -258,7 +258,7 @@ format_params_valid (MuConfig *opts)
opts->formatstr ? opts->formatstr : "<none>");
return FALSE;
}
if (opts->format == MU_CONFIG_FORMAT_LINKS && !opts->linksdir) {
g_warning ("missing --linksdir argument");
return FALSE;
@ -276,15 +276,15 @@ static gboolean
query_params_valid (MuConfig *opts)
{
const gchar *xpath;
xpath = mu_runtime_path (MU_RUNTIME_PATH_XAPIANDB);
if (mu_util_check_dir (xpath, TRUE, FALSE))
return TRUE;
g_warning ("'%s' is not a readable Xapian directory\n", xpath);
g_message ("did you run 'mu index'?");
return FALSE;
}
@ -294,20 +294,20 @@ resolve_bookmark (MuConfig *opts)
MuBookmarks *bm;
char* val;
const gchar *bmfile;
bmfile = mu_runtime_path (MU_RUNTIME_PATH_BOOKMARKS);
bm = mu_bookmarks_new (bmfile);
if (!bm) {
g_warning ("failed to open bookmarks file '%s'", bmfile);
return FALSE;
}
val = (gchar*)mu_bookmarks_lookup (bm, opts->bookmark);
if (!val)
val = (gchar*)mu_bookmarks_lookup (bm, opts->bookmark);
if (!val)
g_warning ("bookmark '%s' not found", opts->bookmark);
else
val = g_strdup (val);
mu_bookmarks_destroy (bm);
return val;
@ -331,7 +331,7 @@ get_query (MuConfig *opts)
if (!bookmarkval)
return NULL;
}
query = mu_util_str_from_strv ((const gchar**)&opts->params[1]);
if (bookmarkval) {
gchar *tmp;
@ -341,20 +341,20 @@ get_query (MuConfig *opts)
}
g_free (bookmarkval);
return query;
}
static gboolean
db_is_ready (const char *xpath)
{
if (mu_util_xapian_is_empty (xpath)) {
{
if (mu_store_database_is_empty (xpath)) {
g_warning ("database is empty; use 'mu index' to "
"add messages");
return FALSE;
}
if (mu_util_xapian_needs_upgrade (xpath)) {
if (mu_store_database_needs_upgrade (xpath)) {
upgrade_warning ();
return FALSE;
}
@ -368,13 +368,13 @@ get_query_obj (void)
GError *err;
const char* xpath;
MuQuery *mquery;
xpath = mu_runtime_path (MU_RUNTIME_PATH_XAPIANDB);
if (!db_is_ready(xpath)) {
g_warning ("database '%s' is not ready", xpath);
return NULL;
}
err = NULL;
mquery = mu_query_new (xpath, &err);
if (!mquery) {
@ -392,7 +392,7 @@ static gboolean
create_linksdir_maybe (const char *linksdir, gboolean clearlinks)
{
GError *err;
err = NULL;
if (access (linksdir, F_OK) != 0) {
if (!mu_maildir_mkdir (linksdir, 0700, TRUE, &err))
@ -402,25 +402,25 @@ create_linksdir_maybe (const char *linksdir, gboolean clearlinks)
goto fail;
return TRUE;
fail:
if (err) {
g_warning ("%s", err->message ? err->message : "unknown error");
g_error_free (err);
}
return FALSE;
return FALSE;
}
static gboolean
link_message (const char *src, const char *destdir)
{
GError *err;
if (access (src, R_OK) != 0) {
if (errno == ENOENT)
g_warning ("cannot find source message %s", src);
else
else
g_warning ("cannot read source message %s: %s", src,
strerror (errno));
return FALSE;
@ -433,9 +433,9 @@ link_message (const char *src, const char *destdir)
err->message : "unknown error");
g_error_free (err);
}
return FALSE;
return FALSE;
}
return TRUE;
}
@ -448,40 +448,40 @@ output_links (MuMsgIter *iter, const char* linksdir,
size_t mycount;
gboolean errseen;
MuMsgIter *myiter;
g_return_val_if_fail (iter, FALSE);
g_return_val_if_fail (linksdir, FALSE);
g_return_val_if_fail (linksdir, FALSE);
/* note: we create the linksdir even if there are no search results */
if (!create_linksdir_maybe (linksdir, clearlinks))
return FALSE;
for (myiter = iter, errseen = FALSE, mycount = 0; !mu_msg_iter_is_done (myiter);
mu_msg_iter_next (myiter)) {
MuMsg *msg;
const char* path;
msg = mu_msg_iter_get_msg (iter, NULL); /* don't unref */
if (!msg)
return FALSE;
path = mu_msg_get_path (msg);
if (!access (path, R_OK)) /* only link to readable */
continue;
if (!link_message (path, linksdir))
errseen = TRUE;
else
++mycount;
}
if (errseen)
if (errseen)
g_warning ("error linking some of the messages");
if (count)
*count = mycount;
return TRUE;
}
@ -494,7 +494,7 @@ ansi_color_maybe (MuMsgFieldId mfid, gboolean color)
if (!color)
return; /* nothing to do */
switch (mfid) {
case MU_MSG_FIELD_ID_FROM:
@ -507,7 +507,7 @@ ansi_color_maybe (MuMsgFieldId mfid, gboolean color)
case MU_MSG_FIELD_ID_SUBJECT:
ansi = MU_COLOR_GREEN; break;
case MU_MSG_FIELD_ID_DATE:
ansi = MU_COLOR_MAGENTA; break;
@ -527,9 +527,9 @@ ansi_reset_maybe (MuMsgFieldId mfid, gboolean color)
{
if (!color)
return; /* nothing to do */
fputs (MU_COLOR_DEFAULT, stdout);
}
@ -537,15 +537,15 @@ static const char*
display_field (MuMsg *msg, MuMsgFieldId mfid)
{
gint64 val;
switch (mu_msg_field_type(mfid)) {
case MU_MSG_FIELD_TYPE_STRING: {
const gchar *str;
str = mu_msg_get_field_string (msg, mfid);
return str ? str : "";
}
}
case MU_MSG_FIELD_TYPE_INT:
if (mfid == MU_MSG_FIELD_ID_PRIO) {
val = mu_msg_get_field_numeric (msg, mfid);
return mu_msg_prio_name ((MuMsgPrio)val);
@ -554,12 +554,12 @@ display_field (MuMsg *msg, MuMsgFieldId mfid)
return mu_str_flags_s ((MuFlags)val);
} else /* as string */
return mu_msg_get_field_string (msg, mfid);
case MU_MSG_FIELD_TYPE_TIME_T:
case MU_MSG_FIELD_TYPE_TIME_T:
val = mu_msg_get_field_numeric (msg, mfid);
return mu_date_str_s ("%c", (time_t)val);
case MU_MSG_FIELD_TYPE_BYTESIZE:
case MU_MSG_FIELD_TYPE_BYTESIZE:
val = mu_msg_get_field_numeric (msg, mfid);
return mu_str_size_s ((unsigned)val);
default:
@ -575,7 +575,7 @@ print_summary (MuMsg *msg)
char *summ;
const guint SUMMARY_LEN = 5; /* summary based on first 5
* lines */
* lines */
err = NULL;
summ = mu_str_summarize (mu_msg_get_body_text(msg), SUMMARY_LEN);
@ -591,14 +591,14 @@ thread_indent (MuMsgIter *iter)
const char* threadpath;
int i;
gboolean is_root, first_child, empty_parent, is_dup;
ti = mu_msg_iter_get_thread_info (iter);
if (!ti) {
g_warning ("cannot get thread-info for %s",
mu_msg_get_subject(mu_msg_iter_get_msg(iter, NULL)));
return;
}
threadpath = ti->threadpath;
/* fputs (threadpath, stdout); */
/* fputs (" ", stdout); */
@ -607,15 +607,15 @@ thread_indent (MuMsgIter *iter)
first_child = ti->prop & MU_MSG_ITER_THREAD_PROP_FIRST_CHILD;
empty_parent = ti->prop & MU_MSG_ITER_THREAD_PROP_EMPTY_PARENT;
is_dup = ti->prop & MU_MSG_ITER_THREAD_PROP_DUP;
/* FIXME: count the colons... */
for (i = 0; *threadpath; ++threadpath)
i += (*threadpath == ':') ? 1 : 0;
/* indent */
while (i --> 0)
fputs (" ", stdout);
if (!is_root) {
fputs (first_child ? "`" : "|", stdout);
fputs (empty_parent ? "*> " : is_dup ? "=> " : "-> ", stdout);
@ -630,7 +630,7 @@ output_plain_fields (MuMsg *msg, const char *fields,
{
const char* myfields;
size_t len;
for (myfields = fields, len = 0; *myfields; ++myfields) {
MuMsgFieldId mfid;
@ -659,22 +659,22 @@ output_plain (MuMsgIter *iter, const char *fields, gboolean summary,
{
MuMsgIter *myiter;
size_t mycount;
g_return_val_if_fail (iter, FALSE);
g_return_val_if_fail (fields, FALSE);
for (myiter = iter, mycount = 0; !mu_msg_iter_is_done (myiter);
mu_msg_iter_next (myiter)) {
size_t len;
MuMsg *msg;
msg = mu_msg_iter_get_msg (iter, NULL); /* don't unref */
if (!msg) {
g_warning ("can't get message");
continue;
}
/* only return messages if they're actually
* readable (ie, live also outside the database) */
if (!include_unreadable && !mu_msg_is_readable (msg))
@ -685,9 +685,9 @@ output_plain (MuMsgIter *iter, const char *fields, gboolean summary,
ansi_color_maybe (MU_MSG_FIELD_ID_PRIO, color);
if (threads)
thread_indent (iter);
len = output_plain_fields (msg, fields, color, threads);
g_print (len > 0 ? "\n" : "");
if (summary)
print_summary (msg);
@ -697,7 +697,7 @@ output_plain (MuMsgIter *iter, const char *fields, gboolean summary,
if (count)
*count = mycount;
return TRUE;
}
@ -705,11 +705,11 @@ static void
print_attr_xml (const char* elm, const char *str)
{
gchar *esc;
if (mu_str_is_empty(str))
return; /* empty: don't include */
esc = g_markup_escape_text (str, -1);
esc = g_markup_escape_text (str, -1);
g_print ("\t\t<%s>%s</%s>\n", elm, esc, elm);
g_free (esc);
}
@ -722,27 +722,27 @@ output_sexp (MuMsgIter *iter, gboolean threads,
{
MuMsgIter *myiter;
size_t mycount;
g_return_val_if_fail (iter, FALSE);
for (myiter = iter, mycount = 0; !mu_msg_iter_is_done (myiter);
mu_msg_iter_next (myiter)) {
MuMsg *msg;
char *sexp;
const MuMsgIterThreadInfo *ti;
msg = mu_msg_iter_get_msg (iter, NULL); /* don't unref */
if (!msg)
return FALSE;
/* only return messages if they're actually
* readable (ie, live also outside the database) */
if (!include_unreadable && !mu_msg_is_readable (msg))
continue;
ti = threads ? mu_msg_iter_get_thread_info (iter) : NULL;
sexp = mu_msg_to_sexp (msg, ti, TRUE);
fputs (sexp, stdout);
g_free (sexp);
@ -750,10 +750,10 @@ output_sexp (MuMsgIter *iter, gboolean threads,
++mycount;
}
if (count)
*count = mycount;
return TRUE;
}
@ -781,34 +781,34 @@ output_xml (MuMsgIter *iter, gboolean include_unreadable, size_t *count)
{
MuMsgIter *myiter;
size_t mycount;
g_return_val_if_fail (iter, FALSE);
g_print ("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
g_print ("<messages>\n");
for (myiter = iter, mycount = 0; !mu_msg_iter_is_done (myiter);
mu_msg_iter_next (myiter)) {
MuMsg *msg;
MuMsg *msg;
msg = mu_msg_iter_get_msg (iter, NULL); /* don't unref */
if (!msg)
return FALSE;
/* only return messages if they're actually
* readable (ie, live also outside the database) */
if (!include_unreadable && !mu_msg_is_readable (msg))
continue;
output_xml_msg (msg);
++mycount;
}
g_print ("</messages>\n");
if (count)
*count = mycount;
return TRUE;
}
@ -820,20 +820,20 @@ mu_cmd_find (MuConfig *opts)
gboolean rv;
gchar *query;
size_t count = 0;
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_FIND,
MU_ERROR_INTERNAL);
if (!query_params_valid (opts) || !format_params_valid(opts))
return MU_ERROR_IN_PARAMETERS;
xapian = get_query_obj();
query = get_query (opts);
if (!xapian ||!query)
return MU_ERROR_INTERNAL;
if (opts->format == MU_CONFIG_FORMAT_XQUERY)
rv = print_xapian_query (xapian, query, &count);
else if (opts->exec)

View File

@ -34,6 +34,7 @@
#include "mu-util.h"
#include "mu-msg.h"
#include "mu-index.h"
#include "mu-store.h"
#include "mu-runtime.h"
static gboolean MU_CAUGHT_SIGNAL;
@ -54,7 +55,7 @@ sig_handler (int sig)
g_warning ("shutting down gracefully, "
"press again to kill immediately");
}
MU_CAUGHT_SIGNAL = TRUE;
}
@ -63,7 +64,7 @@ install_sig_handler (void)
{
struct sigaction action;
int i, sigs[] = { SIGINT, SIGHUP, SIGTERM };
MU_CAUGHT_SIGNAL = FALSE;
action.sa_handler = sig_handler;
@ -86,12 +87,12 @@ check_index_or_cleanup_params (MuConfig *opts)
g_warning ("usage: mu %s [options]", opts->params[0]);
return FALSE;
}
if (opts->linksdir) {
g_warning ("invalid option(s) for command");
return FALSE;
}
if (opts->xbatchsize < 0) {
g_warning ("the Xapian batch size must be non-negative");
return FALSE;
@ -101,7 +102,7 @@ check_index_or_cleanup_params (MuConfig *opts)
g_warning ("the maximum message size must be non-negative");
return FALSE;
}
return TRUE;
}
@ -113,12 +114,12 @@ check_maildir (const char *maildir)
"use --maildir= to set it explicitly");
return FALSE;
}
if (!g_path_is_absolute (maildir)) {
g_warning ("maildir path '%s' is not absolute", maildir);
return FALSE;
}
if (!mu_util_check_dir (maildir, TRUE, FALSE)) {
g_warning ("not a valid Maildir: %s", maildir);
return FALSE;
@ -140,7 +141,7 @@ backspace (unsigned u)
{
static gboolean init = FALSE;
static char backspace[80];
if (G_UNLIKELY(!init)) {
/* fill with backspaces */
int i;
@ -148,7 +149,7 @@ backspace (unsigned u)
backspace[i] = '\b';
init = TRUE;
}
backspace[MIN(u,sizeof(backspace))] = '\0';
fputs (backspace, stdout);
backspace[u] = '\b';
@ -161,11 +162,11 @@ print_stats (MuIndexStats* stats, gboolean clear)
{
const char *kars="-\\|/";
char output[120];
static int i = 0;
static unsigned len = 0;
if (clear)
if (clear)
backspace (len);
len = (unsigned)snprintf (output, sizeof(output),
@ -185,9 +186,9 @@ index_msg_cb (MuIndexStats* stats, void *user_data)
{
if (stats->_processed % 25)
return MU_OK;
print_stats (stats, TRUE);
return MU_CAUGHT_SIGNAL ? MU_STOP: MU_OK;
}
@ -200,27 +201,27 @@ database_version_check_and_update (MuConfig *opts)
xpath = mu_runtime_path (MU_RUNTIME_PATH_XAPIANDB);
ccache = mu_runtime_path (MU_RUNTIME_PATH_CONTACTS);
if (mu_util_xapian_is_empty (xpath))
if (mu_store_database_is_empty (xpath))
return TRUE;
/* when rebuilding, we empty the database before doing
* anything */
if (opts->rebuild) {
opts->reindex = TRUE;
g_message ("clearing database [%s]", xpath);
g_message ("clearing contacts-cache [%s]", ccache);
return mu_util_xapian_clear (xpath, ccache);
return mu_store_database_clear (xpath, ccache);
}
if (!mu_util_xapian_needs_upgrade (xpath))
if (!mu_store_database_needs_upgrade (xpath))
return TRUE; /* ok, nothing to do */
/* ok, database is not up to date */
if (opts->autoupgrade) {
opts->reindex = TRUE;
g_message ("auto-upgrade: clearing old database and cache");
return mu_util_xapian_clear (xpath, ccache);
return mu_store_database_clear (xpath, ccache);
}
update_warning ();
@ -243,7 +244,7 @@ static gboolean
update_maildir_path_maybe (MuIndex *idx, MuConfig *opts)
{
gchar *exp;
/* if 'maildir_guessed' is TRUE, we can override it later
* with mu_index_last_used_maildir (in mu-cmd-index.c)
*/
@ -253,21 +254,21 @@ update_maildir_path_maybe (MuIndex *idx, MuConfig *opts)
/* try the last used one */
tmp = mu_index_last_used_maildir (idx);
if (tmp)
if (tmp)
opts->maildir = g_strdup (tmp);
else
opts->maildir = mu_util_guess_maildir ();
}
if (opts->maildir) {
exp = mu_util_dir_expand(opts->maildir);
if (exp) {
g_free(opts->maildir);
opts->maildir = exp;
}
}
}
return check_maildir (opts->maildir);
return check_maildir (opts->maildir);
}
@ -277,21 +278,21 @@ cmd_cleanup (MuIndex *midx, MuConfig *opts, MuIndexStats *stats,
{
MuError rv;
time_t t;
g_message ("cleaning up messages [%s]",
mu_runtime_path (MU_RUNTIME_PATH_XAPIANDB));
t = time (NULL);
rv = mu_index_cleanup (midx, stats,
show_progress ? index_msg_cb : index_msg_silent_cb,
NULL);
if (!opts->quiet) {
print_stats (stats, TRUE);
g_print ("\n");
show_time ((unsigned)(time(NULL)-t),stats->_processed);
}
return (rv == MU_OK || rv == MU_STOP) ? MU_OK: MU_ERROR;
}
@ -303,15 +304,15 @@ cmd_index (MuIndex *midx, MuConfig *opts, MuIndexStats *stats,
{
MuError rv;
time_t t;
g_message ("indexing messages under %s [%s]", opts->maildir,
mu_runtime_path (MU_RUNTIME_PATH_XAPIANDB));
t = time (NULL);
rv = mu_index_run (midx, opts->maildir, opts->reindex, stats,
show_progress ? index_msg_cb:index_msg_silent_cb,
NULL, NULL);
if (!opts->quiet) {
print_stats (stats, TRUE);
g_print ("\n");
@ -321,7 +322,7 @@ cmd_index (MuIndex *midx, MuConfig *opts, MuIndexStats *stats,
if (rv == MU_OK || rv == MU_STOP)
MU_WRITE_LOG ("index: processed: %u; updated/new: %u",
stats->_processed, stats->_updated);
if (rv == MU_OK && !opts->nocleanup) {
mu_index_stats_clear (stats);
rv = cmd_cleanup (midx, opts, stats, show_progress);
@ -331,7 +332,7 @@ cmd_index (MuIndex *midx, MuConfig *opts, MuIndexStats *stats,
return MU_OK;
}
}
return (rv==MU_OK||rv==MU_STOP) ? MU_OK : MU_ERROR;
}
@ -339,7 +340,7 @@ static MuError
handle_index_error_and_free (GError *err)
{
MuError code;
if (!err)
return MU_ERROR_INTERNAL;
@ -371,7 +372,7 @@ init_mu_index (MuConfig *opts, MuError *code)
{
MuIndex *midx;
GError *err;
if (!check_index_or_cleanup_params (opts)) {
*code = MU_ERROR_IN_PARAMETERS;
return NULL;
@ -381,7 +382,7 @@ init_mu_index (MuConfig *opts, MuError *code)
*code = MU_ERROR_XAPIAN_NOT_UP_TO_DATE;
return NULL;
}
err = NULL;
midx = mu_index_new (mu_runtime_path (MU_RUNTIME_PATH_XAPIANDB),
mu_runtime_path (MU_RUNTIME_PATH_CONTACTS),
@ -390,10 +391,10 @@ init_mu_index (MuConfig *opts, MuError *code)
*code = handle_index_error_and_free (err);
return NULL;
}
mu_index_set_max_msg_size (midx, opts->max_msg_size);
mu_index_set_max_msg_size (midx, opts->max_msg_size);
mu_index_set_xbatch_size (midx, opts->xbatchsize);
return midx;
}
@ -410,13 +411,13 @@ cmd_index_or_cleanup (MuConfig *opts)
midx = init_mu_index (opts, &code);
if (!midx)
return code;
/* we determine the maildir path only here, as it may depend on
* mu_index_last_used_maildir
*/
if (!update_maildir_path_maybe (midx, opts))
return MU_ERROR_FILE;
/* note, 'opts->quiet' already cause g_message output not to
* be shown; here, we make sure we only print progress info if
* opts->quiet is false case and when stdout is a tty */
@ -434,8 +435,8 @@ cmd_index_or_cleanup (MuConfig *opts)
rv = MU_ERROR_INTERNAL;
g_assert_not_reached ();
}
mu_index_destroy (midx);
mu_index_destroy (midx);
return rv;
}
@ -446,7 +447,7 @@ mu_cmd_index (MuConfig *opts)
g_return_val_if_fail (opts, FALSE);
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_INDEX,
FALSE);
return cmd_index_or_cleanup (opts);
}
@ -456,7 +457,7 @@ mu_cmd_cleanup (MuConfig *opts)
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
g_return_val_if_fail (opts->cmd != MU_CONFIG_CMD_CLEANUP,
MU_ERROR_INTERNAL);
return cmd_index_or_cleanup (opts);
}

View File

@ -46,7 +46,12 @@
static gboolean
view_msg_sexp (MuMsg *msg)
{
fputs (mu_msg_to_sexp (msg, NULL, FALSE), stdout);
char *sexp;
sexp = mu_msg_to_sexp (msg, NULL, FALSE);
fputs (sexp, stdout);
g_free (sexp);
return TRUE;
}
@ -77,7 +82,7 @@ get_attach_str (MuMsg *msg)
mu_msg_part_foreach (msg, (MuMsgPartForeachFunc)each_part, &attach);
return attach;
}
}
#define color_maybe(C) do{ if (color) fputs ((C),stdout);}while(0)
@ -86,12 +91,12 @@ print_field (const char* field, const char *val, gboolean color)
{
if (!val)
return;
color_maybe (MU_COLOR_MAGENTA);
mu_util_fputs_encoded (field, stdout);
color_maybe (MU_COLOR_DEFAULT);
fputs (": ", stdout);
if (val) {
color_maybe (MU_COLOR_GREEN);
mu_util_fputs_encoded (val, stdout);
@ -107,11 +112,11 @@ body_or_summary (MuMsg *msg, gboolean summary, gboolean color)
{
const char* field;
const int SUMMARY_LEN = 5;
field = mu_msg_get_body_text (msg);
if (!field)
return; /* no body -- nothing more to do */
if (summary) {
gchar *summ;
summ = mu_str_summarize (field, SUMMARY_LEN);
@ -133,14 +138,14 @@ view_msg_plain (MuMsg *msg, const gchar *fields, gboolean summary,
gchar *attachs;
time_t date;
const GSList *lst;
print_field ("From", mu_msg_get_from (msg), color);
print_field ("To", mu_msg_get_to (msg), color);
print_field ("Cc", mu_msg_get_cc (msg), color);
print_field ("Bcc", mu_msg_get_bcc (msg), color);
print_field ("Subject", mu_msg_get_subject (msg), color);
if ((date = mu_msg_get_date (msg)))
if ((date = mu_msg_get_date (msg)))
print_field ("Date", mu_date_str_s ("%c", date),
color);
@ -150,7 +155,7 @@ view_msg_plain (MuMsg *msg, const gchar *fields, gboolean summary,
print_field ("Tags", tags, color);
g_free (tags);
}
if ((attachs = get_attach_str (msg))) {
print_field ("Attachments", attachs, color);
g_free (attachs);
@ -168,13 +173,15 @@ handle_msg (const char *fname, MuConfig *opts, MuError *code)
GError *err;
MuMsg *msg;
gboolean rv;
err = NULL;
msg = mu_msg_new_from_file (fname, NULL, &err);
if (!msg) {
g_warning ("error: %s", err->message);
g_error_free (err);
if (err && err->message) {
g_warning ("%s", err->message);
g_error_free (err);
}
*code = MU_ERROR;
return FALSE;
}
@ -191,7 +198,7 @@ handle_msg (const char *fname, MuConfig *opts, MuError *code)
*code = MU_ERROR_INTERNAL;
rv = FALSE;
}
mu_msg_unref (msg);
return rv;
@ -205,7 +212,7 @@ view_params_valid (MuConfig *opts)
g_warning ("usage: mu view [options] <file> [<files>]");
return FALSE;
}
switch (opts->format) {
case MU_CONFIG_FORMAT_PLAIN:
case MU_CONFIG_FORMAT_SEXP:
@ -215,7 +222,7 @@ view_params_valid (MuConfig *opts)
opts->formatstr ? opts->formatstr : "<none>");
return FALSE;
}
return TRUE;
}
@ -226,14 +233,14 @@ mu_cmd_view (MuConfig *opts)
int i;
gboolean rv;
MuError code;
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_VIEW,
MU_ERROR_INTERNAL);
if (!view_params_valid(opts))
return MU_ERROR_IN_PARAMETERS;
for (i = 1, code = MU_OK; opts->params[i]; ++i) {
rv = handle_msg (opts->params[i], opts, &code);
@ -243,7 +250,7 @@ mu_cmd_view (MuConfig *opts)
if (opts->terminator)
g_print ("%c", VIEW_TERMINATOR);
}
return code;
}
@ -252,17 +259,17 @@ MuError
mu_cmd_mkdir (MuConfig *opts)
{
int i;
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_MKDIR,
MU_ERROR_INTERNAL);
if (!opts->params[1]) {
g_warning ("usage: mu mkdir [-u,--mode=<mode>] "
"<dir> [more dirs]");
return MU_ERROR_IN_PARAMETERS;
}
for (i = 1; opts->params[i]; ++i) {
GError *err;
@ -309,7 +316,7 @@ mv_check_params (MuConfig *opts, MuFlags *flags)
MU_FLAG_TYPE_MAILDIR |
MU_FLAG_TYPE_MAILFILE);
}
return TRUE;
}
@ -321,7 +328,7 @@ cmd_mv_dev_null (MuConfig *opts)
g_warning ("unlink failed: %s", strerror (errno));
return MU_ERROR_FILE;
}
if (opts->print_target)
g_print ("/dev/null\n"); /* /dev/null */
@ -335,7 +342,7 @@ mu_cmd_mv (MuConfig *opts)
GError *err;
gchar *fullpath;
MuFlags flags;
if (!mv_check_params (opts, &flags))
return MU_ERROR_IN_PARAMETERS;
@ -357,19 +364,19 @@ mu_cmd_mv (MuConfig *opts)
return code;
}
return MU_ERROR_FILE;
} else {
if (opts->print_target)
g_print ("%s\n", fullpath);
if (opts->print_target)
g_print ("%s\n", fullpath);
return MU_OK;
}
g_free (fullpath);
return MU_OK;
}
static gboolean
check_file_okay (const char *path, gboolean cmd_add)
{
@ -377,7 +384,7 @@ check_file_okay (const char *path, gboolean cmd_add)
g_warning ("path is not absolute: %s", path);
return FALSE;
}
if (cmd_add && access(path, R_OK) != 0) {
g_warning ("path is not readable: %s: %s",
path, strerror (errno));
@ -386,7 +393,7 @@ check_file_okay (const char *path, gboolean cmd_add)
return TRUE;
}
static MuStore*
get_store (void)
@ -395,9 +402,10 @@ get_store (void)
GError *err;
err = NULL;
store = mu_store_new (mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
mu_runtime_path(MU_RUNTIME_PATH_CONTACTS),
&err);
store = mu_store_new_writable
(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
mu_runtime_path(MU_RUNTIME_PATH_CONTACTS),
&err);
if (!store) {
if (err) {
g_warning ("store error: %s", err->message);
@ -407,18 +415,16 @@ get_store (void)
}
return store;
}
MuError
mu_cmd_add (MuConfig *opts)
{
MuStore *store;
gboolean allok;
int i;
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_ADD,
MU_ERROR_INTERNAL);
@ -432,9 +438,9 @@ mu_cmd_add (MuConfig *opts)
store = get_store ();
if (!store)
return MU_ERROR_INTERNAL;
for (i = 1, allok = TRUE; opts->params[i]; ++i) {
const char* src;
src = opts->params[i];
@ -442,13 +448,13 @@ mu_cmd_add (MuConfig *opts)
allok = FALSE;
continue;
}
if (!mu_store_store_path (store, src)) {
allok = FALSE;
g_warning ("failed to store %s", src);
}
}
mu_store_destroy (store);
return allok ? MU_OK : MU_ERROR;
@ -461,7 +467,7 @@ mu_cmd_remove (MuConfig *opts)
MuStore *store;
gboolean allok;
int i;
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_REMOVE,
MU_ERROR_INTERNAL);
@ -475,9 +481,9 @@ mu_cmd_remove (MuConfig *opts)
store = get_store ();
if (!store)
return MU_ERROR_INTERNAL;
for (i = 1, allok = TRUE; opts->params[i]; ++i) {
const char* src;
src = opts->params[i];
@ -485,14 +491,17 @@ mu_cmd_remove (MuConfig *opts)
allok = FALSE;
continue;
}
if (!mu_store_remove_path (store, src)) {
allok = FALSE;
g_warning ("failed to remove %s", src);
}
}
mu_store_destroy (store);
return allok ? MU_OK : MU_ERROR;
}

View File

@ -33,8 +33,8 @@ G_BEGIN_DECLS
*
* @param opts configuration options
*
* @return MU_EXITCODE_OK (0) if the command succeeded,
* MU_EXITCODE_ERROR otherwise
* @return MU_OK (0) if the command succeeded,
* some error code otherwise
*/
MuError mu_cmd_mkdir (MuConfig *opts);
@ -44,30 +44,32 @@ MuError mu_cmd_mkdir (MuConfig *opts);
*
* @param opts configuration options
*
* @return MU_EXITCODE_OK (0) if the command succeeded,
* MU_EXITCODE_ERROR otherwise
* @return MU_OK (0) if the command succeeded,
* some error code otherwise
*/
MuError mu_cmd_view (MuConfig *opts);
/**
* execute the 'index' command
*
*
* @param store store object to use
* @param opts configuration options
*
* @return MU_EXITCODE_OK (0) if the command succeeded,
* MU_EXITCODE_ERROR otherwise
* @return MU_OK (0) if the command succeeded,
* some error code otherwise
*/
MuError mu_cmd_index (MuConfig *opts);
/**
* execute the 'cleanup' command
*
*
* @param store store object to use
* @param opts configuration options
*
* @return MU_EXITCODE_OK (0) if the command succeeds,
* MU_EXITCODE_ERROR otherwise
* @return MU_OK (0) if the command succeeds,
* some error code otherwise
*/
MuError mu_cmd_cleanup (MuConfig *opts);
@ -76,9 +78,9 @@ MuError mu_cmd_cleanup (MuConfig *opts);
*
* @param opts configuration options
*
* @return MU_EXITCODE_OK (0) if the command succeeds and
* >MU_EXITCODE_OK (0) results, MU_EXITCODE_NO_MATCHES if the command
* succeeds but there no matches, MU_EXITCODE_ERROR for all other errors
* @return MU_OK (0) if the command succeeds and
* >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 (MuConfig *opts);
@ -88,8 +90,8 @@ MuError mu_cmd_find (MuConfig *opts);
*
* @param opts configuration options
*
* @return MU_EXITCODE_OK (0) if the command succeeds,
* MU_EXITCODE_ERROR otherwise
* @return MU_OK (0) if the command succeeds,
* some error code otherwise
*/
MuError mu_cmd_extract (MuConfig *opts);
@ -99,21 +101,18 @@ MuError mu_cmd_extract (MuConfig *opts);
*
* @param opts configuration options
*
* @return MU_EXITCODE_OK (0) if the command succeeds,
* MU_EXITCODE_ERROR otherwise
* @return MU_OK (0) if the command succeeds,
* some error code otherwise
*/
MuError mu_cmd_mv (MuConfig *opts);
/**
* execute the cfind command
*
* @param opts configuration options
*
* @return MU_EXITCODE_OK (0) if the command succeeds,
* MU_EXITCODE_ERROR otherwise
* @return MU_OK (0) if the command succeeds,
* some error code otherwise
*/
MuError mu_cmd_cfind (MuConfig *opts);
@ -123,8 +122,8 @@ MuError mu_cmd_cfind (MuConfig *opts);
*
* @param opts configuration options
*
* @return MU_EXITCODE_OK (0) if the command succeeds,
* MU_EXITCODE_ERROR otherwise
* @return MU_OK (0) if the command succeeds,
* some error code otherwise
*/
MuError mu_cmd_add (MuConfig *opts);
@ -133,11 +132,23 @@ MuError mu_cmd_add (MuConfig *opts);
*
* @param opts configuration options
*
* @return MU_EXITCODE_OK (0) if the command succeeds,
* MU_EXITCODE_ERROR otherwise
* @return MU_OK (0) if the command succeeds,
* some error code otherwise
*/
MuError mu_cmd_remove (MuConfig *opts);
/**
* execute the server command
*
* @param opts configuration options
*
* @return MU_OK (0) if the command succeeds,
* some error code otherwise
*/
MuError mu_cmd_server (MuConfig *opts);
G_END_DECLS
#endif /*__MU_CMD_H__*/

View File

@ -1,22 +1,22 @@
/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/
/*
/*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify
1** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#ifdef HAVE_CONFIG_H
@ -46,40 +46,40 @@ struct _MuIndex {
guint _max_filesize;
};
MuIndex*
MuIndex*
mu_index_new (const char *xpath, const char* contacts_cache, GError **err)
{
MuIndex *index;
g_return_val_if_fail (xpath, NULL);
index = g_new0 (MuIndex, 1);
index->_store = mu_store_new (xpath, contacts_cache, err);
index = g_new0 (MuIndex, 1);
index->_store = mu_store_new_writable (xpath, contacts_cache, err);
if (!index->_store) {
g_warning ("%s: failed to open xapian store (%s)",
__FUNCTION__, xpath);
__FUNCTION__, xpath);
g_free (index);
return NULL;
}
/* set the default max file size */
index->_max_filesize = MU_INDEX_MAX_FILE_SIZE;
/* see we need to reindex the database; note, there is a small
* race-condition here, between mu_index_new and
* mu_index_run. Maybe do the check in mu_index_run
* instead? */
if (mu_util_xapian_is_empty (xpath))
if (mu_store_database_is_empty (xpath))
index->_needs_reindex = FALSE;
else
index->_needs_reindex =
mu_util_xapian_needs_upgrade (xpath);
mu_store_database_needs_upgrade (xpath);
return index;
}
void
void
mu_index_destroy (MuIndex *index)
{
if (!index)
@ -116,7 +116,7 @@ needs_index (MuIndexCallbackData *data, const char *fullpath,
/* unconditionally reindex */
if (data->_reindex)
return TRUE;
/* it's not in the database yet */
if (!mu_store_contains_message (data->_store, fullpath))
return TRUE;
@ -133,14 +133,14 @@ static MuError
insert_or_update_maybe (const char* fullpath, const char* mdir,
time_t filestamp, MuIndexCallbackData *data,
gboolean *updated)
{
{
MuMsg *msg;
GError *err;
*updated = FALSE;
if (!needs_index (data, fullpath, filestamp))
return MU_OK; /* nothing to do for this one */
err = NULL;
msg = mu_msg_new_from_file (fullpath, mdir, &err);
if ((G_UNLIKELY(!msg))) {
@ -148,18 +148,18 @@ insert_or_update_maybe (const char* fullpath, const char* mdir,
__FUNCTION__, fullpath);
return MU_ERROR;
}
/* we got a valid id; scan the message contents as well */
if (G_UNLIKELY((!mu_store_store_msg (data->_store, msg, TRUE)))) {
g_warning ("%s: storing content %s failed", __FUNCTION__,
g_warning ("%s: storing content %s failed", __FUNCTION__,
fullpath);
return MU_ERROR;
}
}
mu_msg_unref (msg);
*updated = TRUE;
return MU_OK;
return MU_OK;
}
static MuError
@ -169,9 +169,9 @@ run_msg_callback_maybe (MuIndexCallbackData *data)
if (!data || !data->_idx_msg_cb)
return MU_OK;
result = data->_idx_msg_cb (data->_stats, data->_user_data);
if G_UNLIKELY((result != MU_OK && result != MU_STOP))
if (G_UNLIKELY(result != MU_OK && result != MU_STOP))
g_warning ("error in callback");
return result;
@ -191,17 +191,17 @@ on_run_maildir_msg (const char* fullpath, const char* mdir,
data->_max_filesize, fullpath);
return MU_OK; /* not an error */
}
result = run_msg_callback_maybe (data);
if (result != MU_OK)
return result;
/* see if we need to update/insert anything...
* use the ctime, so any status change will be visible (perms,
* filename etc.)*/
result = insert_or_update_maybe (fullpath, mdir, statbuf->st_ctime,
data, &updated);
if (result == MU_OK && data && data->_stats) { /* update statistics */
++data->_stats->_processed;
updated ? ++data->_stats->_updated : ++data->_stats->_uptodate;
@ -212,7 +212,7 @@ on_run_maildir_msg (const char* fullpath, const char* mdir,
static MuError
on_run_maildir_dir (const char* fullpath, gboolean enter,
on_run_maildir_dir (const char* fullpath, gboolean enter,
MuIndexCallbackData *data)
{
/* xapian stores a per-dir timestamp; we use this timestamp
@ -231,9 +231,9 @@ on_run_maildir_dir (const char* fullpath, gboolean enter,
g_debug ("leaving %s (ts=%u)",
fullpath, (unsigned)data->_dirstamp);
}
if (data->_idx_dir_cb)
return data->_idx_dir_cb (fullpath, enter,
return data->_idx_dir_cb (fullpath, enter,
data->_user_data);
return MU_OK;
@ -249,37 +249,37 @@ check_path (const char* path)
__FUNCTION__, path);
return FALSE;
}
if (access (path, R_OK) != 0) {
g_warning ("%s: cannot open '%s': %s",
g_warning ("%s: cannot open '%s': %s",
__FUNCTION__, path, strerror (errno));
return FALSE;
}
return TRUE;
}
static void
init_cb_data (MuIndexCallbackData *cb_data, MuStore *xapian,
gboolean reindex, guint max_filesize, MuIndexStats *stats,
MuIndexMsgCallback msg_cb, MuIndexDirCallback dir_cb,
MuIndexMsgCallback msg_cb, MuIndexDirCallback dir_cb,
void *user_data)
{
cb_data->_idx_msg_cb = msg_cb;
cb_data->_idx_dir_cb = dir_cb;
cb_data->_user_data = user_data;
cb_data->_store = xapian;
cb_data->_reindex = reindex;
cb_data->_dirstamp = 0;
cb_data->_dirstamp = 0;
cb_data->_max_filesize = max_filesize;
cb_data->_stats = stats;
if (cb_data->_stats)
memset (cb_data->_stats, 0, sizeof(MuIndexStats));
}
static void
update_last_used_maildir (MuIndex *index, const char *path)
{
@ -294,7 +294,7 @@ mu_index_last_used_maildir (MuIndex *index)
{
g_return_val_if_fail (index, NULL);
g_free (index->_last_used_maildir);
return index->_last_used_maildir =
mu_store_get_metadata (index->_store,
MU_LAST_USED_MAILDIR_KEY);
@ -324,48 +324,48 @@ mu_index_set_xbatch_size (MuIndex *index, guint xbatchsize)
MuError
mu_index_run (MuIndex *index, const char* path,
gboolean reindex, MuIndexStats *stats,
MuIndexMsgCallback msg_cb, MuIndexDirCallback dir_cb,
MuIndexMsgCallback msg_cb, MuIndexDirCallback dir_cb,
void *user_data)
{
MuIndexCallbackData cb_data;
MuError rv;
g_return_val_if_fail (index && index->_store, MU_ERROR);
g_return_val_if_fail (msg_cb, MU_ERROR);
if (!check_path (path))
return MU_ERROR;
if (!reindex && index->_needs_reindex) {
g_warning ("database not up-to-date; needs full reindex");
return MU_ERROR;
}
init_cb_data (&cb_data, index->_store, reindex,
index->_max_filesize, stats,
msg_cb, dir_cb, user_data);
update_last_used_maildir (index, path);
rv = mu_maildir_walk (path,
(MuMaildirWalkMsgCallback)on_run_maildir_msg,
(MuMaildirWalkDirCallback)on_run_maildir_dir,
&cb_data);
mu_store_flush (index->_store);
return rv;
}
static MuError
on_stats_maildir_file (const char *fullpath, const char* mdir,
struct stat *statbuf,
struct stat *statbuf,
MuIndexCallbackData *cb_data)
{
MuError result;
if (cb_data && cb_data->_idx_msg_cb)
result = cb_data->_idx_msg_cb (cb_data->_stats,
result = cb_data->_idx_msg_cb (cb_data->_stats,
cb_data->_user_data);
else
result = MU_OK;
@ -374,7 +374,7 @@ on_stats_maildir_file (const char *fullpath, const char* mdir,
if (cb_data->_stats)
++cb_data->_stats->_processed;
return MU_OK;
}
}
return result; /* MU_STOP or MU_OK */
}
@ -386,16 +386,16 @@ mu_index_stats (MuIndex *index, const char* path,
MuIndexDirCallback cb_dir, void *user_data)
{
MuIndexCallbackData cb_data;
g_return_val_if_fail (index, MU_ERROR);
g_return_val_if_fail (cb_msg, MU_ERROR);
if (!check_path (path))
return MU_ERROR;
if (stats)
memset (stats, 0, sizeof(MuIndexStats));
cb_data._idx_msg_cb = cb_msg;
cb_data._idx_dir_cb = cb_dir;
@ -403,19 +403,18 @@ mu_index_stats (MuIndex *index, const char* path,
cb_data._user_data = user_data;
cb_data._dirstamp = 0;
return mu_maildir_walk (path,
(MuMaildirWalkMsgCallback)on_stats_maildir_file,
NULL,&cb_data);
}
struct _CleanupData {
MuStore *_store;
MuIndexStats *_stats;
MuIndexCleanupDeleteCallback _cb;
void *_user_data;
};
typedef struct _CleanupData CleanupData;
@ -434,7 +433,7 @@ foreach_doc_cb (const char* path, CleanupData *cudata)
if (cudata->_stats)
++cudata->_stats->_processed;
if (!cudata->_cb)
return MU_OK;
@ -449,15 +448,15 @@ mu_index_cleanup (MuIndex *index, MuIndexStats *stats,
{
MuError rv;
CleanupData cudata;
g_return_val_if_fail (index, MU_ERROR);
g_return_val_if_fail (cb, MU_ERROR);
cudata._store = index->_store;
cudata._stats = stats;
cudata._cb = cb;
cudata._user_data = user_data;
rv = mu_store_foreach (index->_store,
(MuStoreForeachFunc)foreach_doc_cb,
&cudata);

View File

@ -297,7 +297,7 @@ mu_msg_to_sexp (MuMsg *msg, const MuMsgIterThreadInfo *ti, gboolean dbonly)
if (!dbonly)
append_sexp_message_file_attr (gstr, msg);
g_string_append (gstr, ")\n;;eom\n");
g_string_append (gstr, ")\n;;eox\n");
return g_string_free (gstr, FALSE);
}

View File

@ -6,16 +6,16 @@
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#include <string.h>
@ -47,13 +47,13 @@ static void
gmime_init (void)
{
g_return_if_fail (!_gmime_initialized);
#ifdef GMIME_ENABLE_RFC2047_WORKAROUNDS
g_mime_init(GMIME_ENABLE_RFC2047_WORKAROUNDS);
#else
g_mime_init(0);
#endif /* GMIME_ENABLE_RFC2047_WORKAROUNDS */
_gmime_initialized = TRUE;
}
@ -61,7 +61,7 @@ static void
gmime_uninit (void)
{
g_return_if_fail (_gmime_initialized);
g_mime_shutdown();
_gmime_initialized = FALSE;
}
@ -71,17 +71,12 @@ static MuMsg*
msg_new (void)
{
MuMsg *self;
if (G_UNLIKELY(!_gmime_initialized)) {
gmime_init ();
g_atexit (gmime_uninit);
}
self = g_slice_new0 (MuMsg);
self->_refcount = 1;
self->_cache = mu_msg_cache_new ();
return self;
}
@ -90,16 +85,21 @@ mu_msg_new_from_file (const char *path, const char *mdir, GError **err)
{
MuMsg *self;
MuMsgFile *msgfile;
g_return_val_if_fail (path, NULL);
if (G_UNLIKELY(!_gmime_initialized)) {
gmime_init ();
g_atexit (gmime_uninit);
}
msgfile = mu_msg_file_new (path, mdir, err);
if (!msgfile)
if (!msgfile)
return NULL;
self = msg_new ();
self->_file = msgfile;
return self;
}
@ -109,21 +109,26 @@ mu_msg_new_from_doc (XapianDocument *doc, GError **err)
{
MuMsg *self;
MuMsgDoc *msgdoc;
g_return_val_if_fail (doc, NULL);
if (G_UNLIKELY(!_gmime_initialized)) {
gmime_init ();
g_atexit (gmime_uninit);
}
msgdoc = mu_msg_doc_new (doc, err);
if (!msgdoc)
return NULL;
self = msg_new ();
self->_doc = msgdoc;
return self;
}
static void
static void
mu_msg_destroy (MuMsg *self)
{
if (!self)
@ -133,7 +138,7 @@ mu_msg_destroy (MuMsg *self)
mu_msg_doc_destroy (self->_doc);
mu_msg_cache_destroy (self->_cache);
g_slice_free (MuMsg, self);
}
@ -144,7 +149,7 @@ mu_msg_ref (MuMsg *self)
g_return_val_if_fail (self, NULL);
++self->_refcount;
return self;
}
@ -153,8 +158,8 @@ mu_msg_unref (MuMsg *self)
{
g_return_if_fail (self);
g_return_if_fail (self->_refcount >= 1);
if (--self->_refcount == 0)
if (--self->_refcount == 0)
mu_msg_destroy (self);
}
@ -167,7 +172,7 @@ get_path (MuMsg *self)
const char *path;
char *val;
gboolean do_free;
/* try to get the path from the cache */
path = mu_msg_cache_str (self->_cache, MU_MSG_FIELD_ID_PATH);
if (path)
@ -180,14 +185,14 @@ get_path (MuMsg *self)
val = mu_msg_doc_get_str_field (self->_doc,
MU_MSG_FIELD_ID_PATH,
&do_free);
/* not in the cache yet? try to get it from the file backend,
* in case we are using that */
if (!val && self->_file)
val = mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_PATH,
&do_free);
/* this cannot happen unless there are bugs in mu */
if (!val) {
g_warning ("%s: cannot find path", __FUNCTION__);
@ -211,7 +216,7 @@ get_msg_file (MuMsg *self)
if (!(path = get_path (self)))
return NULL;
err = NULL;
mfile = mu_msg_file_new (path, NULL, &err);
if (!mfile) {
@ -220,7 +225,7 @@ get_msg_file (MuMsg *self)
g_error_free (err);
return NULL;
}
return mfile;
}
@ -251,7 +256,7 @@ get_str_list_field (MuMsg *self, MuMsgFieldId mfid)
val = mu_msg_file_get_str_list_field (self->_file, mfid,
&do_free);
}
/* if we get a string that needs freeing, we tell the cache to
* mark the string as such, so it will be freed when the cache
* is freed (or when the value is overwritten) */
@ -289,7 +294,7 @@ get_str_field (MuMsg *self, MuMsgFieldId mfid)
g_warning ("%s: cannot retrieve field", __FUNCTION__);
return NULL;
}
/* if we get a string that needs freeing, we tell the cache to
* mark the string as such, so it will be freed when the cache
* is freed (or when the value is overwritten) */
@ -301,10 +306,10 @@ static gint64
get_num_field (MuMsg *self, MuMsgFieldId mfid)
{
guint64 val;
if (mu_msg_cache_cached (self->_cache, mfid))
return mu_msg_cache_num (self->_cache, mfid);
/* if it's not in the cache but it is a value retrievable from
* the doc backend, use that */
val = -1;
@ -341,7 +346,7 @@ mu_msg_get_header (MuMsg *self, const char *header)
}
const char*
const char*
mu_msg_get_path (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
@ -349,21 +354,21 @@ mu_msg_get_path (MuMsg *self)
}
const char*
const char*
mu_msg_get_subject (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_SUBJECT);
}
const char*
const char*
mu_msg_get_msgid (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_MSGID);
}
const char*
const char*
mu_msg_get_maildir (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
@ -371,7 +376,7 @@ mu_msg_get_maildir (MuMsg *self)
}
const char*
const char*
mu_msg_get_from (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
@ -379,14 +384,14 @@ mu_msg_get_from (MuMsg *self)
}
const char*
const char*
mu_msg_get_to (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_TO);
}
const char*
const char*
mu_msg_get_cc (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
@ -394,7 +399,7 @@ mu_msg_get_cc (MuMsg *self)
}
const char*
const char*
mu_msg_get_bcc (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
@ -504,7 +509,7 @@ mu_msg_contact_new (const char *name, const char *address,
MuMsgContactType type)
{
MuMsgContact *self;
g_return_val_if_fail (name, NULL);
g_return_val_if_fail (address, NULL);
g_return_val_if_fail (!mu_msg_contact_type_is_valid(type),
@ -516,7 +521,7 @@ mu_msg_contact_new (const char *name, const char *address,
self->address = g_strdup (address);
self->type = type;
return self;
return self;
}
@ -531,7 +536,7 @@ mu_msg_contact_destroy (MuMsgContact *self)
g_free ((void*)self->address);
g_slice_free (MuMsgContact, self);
}
static gboolean
fill_contact (MuMsgContact *self, InternetAddress *addr,
@ -539,10 +544,10 @@ fill_contact (MuMsgContact *self, InternetAddress *addr,
{
if (!addr)
return FALSE;
self->name = internet_address_get_name (addr);
self->type = ctype;
self->type = ctype;
/* we only support internet mailbox addresses; if we don't
* check, g_mime hits an assert
*/
@ -551,7 +556,7 @@ fill_contact (MuMsgContact *self, InternetAddress *addr,
(INTERNET_ADDRESS_MAILBOX(addr));
else
self->address = NULL;
return TRUE;
}
@ -561,16 +566,16 @@ address_list_foreach (InternetAddressList *addrlist, MuMsgContactType ctype,
MuMsgContactForeachFunc func, gpointer user_data)
{
int i;
for (i = 0; addrlist && i != internet_address_list_length(addrlist);
++i) {
MuMsgContact contact;
if (!fill_contact(&contact,
internet_address_list_get_address (addrlist, i),
ctype))
continue;
if (!(func)(&contact, user_data))
break;
}
@ -582,10 +587,10 @@ addresses_foreach (const char* addrs, MuMsgContactType ctype,
MuMsgContactForeachFunc func, gpointer user_data)
{
InternetAddressList *addrlist;
if (!addrs)
return;
addrlist = internet_address_list_parse_string (addrs);
if (addrlist) {
address_list_foreach (addrlist, ctype, func, user_data);
@ -595,11 +600,11 @@ addresses_foreach (const char* addrs, MuMsgContactType ctype,
void
msg_contact_foreach_file (MuMsg *msg, MuMsgContactForeachFunc func,
msg_contact_foreach_file (MuMsg *msg, MuMsgContactForeachFunc func,
gpointer user_data)
{
int i;
struct {
int i;
struct {
GMimeRecipientType _gmime_type;
MuMsgContactType _type;
} ctypes[] = {
@ -611,7 +616,7 @@ msg_contact_foreach_file (MuMsg *msg, MuMsgContactForeachFunc func,
/* sender */
addresses_foreach (g_mime_message_get_sender (msg->_file->_mime_msg),
MU_MSG_CONTACT_TYPE_FROM, func, user_data);
/* get to, cc, bcc */
for (i = 0; i != G_N_ELEMENTS(ctypes); ++i) {
InternetAddressList *addrlist;
@ -623,7 +628,7 @@ msg_contact_foreach_file (MuMsg *msg, MuMsgContactForeachFunc func,
static void
msg_contact_foreach_doc (MuMsg *msg, MuMsgContactForeachFunc func,
msg_contact_foreach_doc (MuMsg *msg, MuMsgContactForeachFunc func,
gpointer user_data)
{
addresses_foreach (mu_msg_get_from (msg),
@ -638,7 +643,7 @@ msg_contact_foreach_doc (MuMsg *msg, MuMsgContactForeachFunc func,
void
mu_msg_contact_foreach (MuMsg *msg, MuMsgContactForeachFunc func,
mu_msg_contact_foreach (MuMsg *msg, MuMsgContactForeachFunc func,
gpointer user_data)
{
g_return_if_fail (msg);
@ -663,7 +668,7 @@ cmp_str (const char* s1, const char *s2)
return -1;
else if (!s2)
return 1;
return g_utf8_collate (s1, s2);
}
@ -677,7 +682,7 @@ cmp_subject (const char* s1, const char *s2)
return -1;
else if (!s2)
return 1;
return g_utf8_collate (
mu_str_subject_normalize (s1),
mu_str_subject_normalize (s2));
@ -690,19 +695,19 @@ mu_msg_cmp (MuMsg *m1, MuMsg *m2, MuMsgFieldId mfid)
g_return_val_if_fail (m1, 0);
g_return_val_if_fail (m2, 0);
g_return_val_if_fail (mu_msg_field_id_is_valid(mfid), 0);
if (mfid == MU_MSG_FIELD_ID_SUBJECT)
if (mfid == MU_MSG_FIELD_ID_SUBJECT)
return cmp_subject (get_str_field (m1, mfid),
get_str_field (m2, mfid));
if (mu_msg_field_is_string (mfid))
if (mu_msg_field_is_string (mfid))
return cmp_str (get_str_field (m1, mfid),
get_str_field (m2, mfid));
/* TODO: note, we cast (potentially > MAXINT to int) */
if (mu_msg_field_is_numeric (mfid))
if (mu_msg_field_is_numeric (mfid))
return get_num_field(m1, mfid) - get_num_field(m2, mfid);
return 0; /* TODO: handle lists */
}
@ -711,7 +716,7 @@ gboolean
mu_msg_is_readable (MuMsg *self)
{
g_return_val_if_fail (self, FALSE);
return (access (get_str_field (self, MU_MSG_FIELD_ID_PATH), R_OK)
== 0) ? TRUE : FALSE;
}
@ -726,7 +731,7 @@ mu_msg_move_to_maildir (MuMsg *self, const char* targetmdir,
MuFlags flags, gboolean ignore_dups, GError **err)
{
char *newfullpath;
g_return_val_if_fail (self, FALSE);
newfullpath = mu_maildir_move_message (mu_msg_get_path (self),
@ -735,7 +740,7 @@ mu_msg_move_to_maildir (MuMsg *self, const char* targetmdir,
if (newfullpath) /* update our path to new one... */
mu_msg_cache_set_str (self->_cache, MU_MSG_FIELD_ID_PATH, newfullpath,
TRUE); /* the cache will free the string */
return newfullpath ? TRUE : FALSE;
}

View File

@ -1,20 +1,20 @@
/*
/*
** Copyright (C) 2008-2011 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 Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#include <stdexcept>
@ -48,16 +48,16 @@ public:
if (!clear_prefix (begin))
return Xapian::BAD_VALUENO;
begin = to_sortable (begin, true);
end = to_sortable (end, false);
if (begin > end)
if (begin > end)
throw Xapian::QueryParserError
("end time is before begin");
return (Xapian::valueno)MU_MSG_FIELD_ID_DATE;
}
private:
@ -65,18 +65,18 @@ private:
const char* str;
time_t t;
str = mu_date_interpret_s (s.c_str(), is_begin ? TRUE: FALSE);
str = mu_date_complete_s (str, is_begin ? TRUE: FALSE);
t = mu_date_str_to_time_t (str, TRUE /*local*/);
str = mu_date_time_t_to_str (t, FALSE /*UTC*/);
return s = std::string(str);
}
bool clear_prefix (std::string& begin) {
const std::string colon (":");
const std::string name (mu_msg_field_name
(MU_MSG_FIELD_ID_DATE) + colon);
@ -91,10 +91,10 @@ private:
begin.erase (0, shortcut.length());
return true;
} else
return false;
return false;
}
};
@ -103,12 +103,12 @@ public:
MuSizeRangeProcessor():
Xapian::NumberValueRangeProcessor(MU_MSG_FIELD_ID_SIZE) {
}
Xapian::valueno operator()(std::string &begin, std::string &end) {
if (!clear_prefix (begin))
return Xapian::BAD_VALUENO;
if (!substitute_size (begin) || !substitute_size (end))
return Xapian::BAD_VALUENO;
@ -118,19 +118,19 @@ public:
begin = Xapian::sortable_serialise (atol(begin.c_str()));
end = Xapian::sortable_serialise (atol(end.c_str()));
return (Xapian::valueno)MU_MSG_FIELD_ID_SIZE;
}
private:
bool clear_prefix (std::string& begin) {
const std::string colon (":");
const std::string name (mu_msg_field_name
(MU_MSG_FIELD_ID_SIZE) + colon);
const std::string shortcut (
std::string(1, mu_msg_field_shortcut
(MU_MSG_FIELD_ID_SIZE)) + colon);
if (begin.find (name) == 0) {
begin.erase (0, name.length());
return true;
@ -138,9 +138,9 @@ private:
begin.erase (0, shortcut.length());
return true;
} else
return false;
return false;
}
bool substitute_size (std::string& size) {
gchar str[16];
gint64 num = mu_str_size_parse_bkm(size.c_str());
@ -157,19 +157,27 @@ private:
static void add_prefix (MuMsgFieldId field, Xapian::QueryParser* qparser);
struct _MuQuery {
_MuQuery (const char* dbpath):
_db (Xapian::Database(dbpath)) {
_MuQuery (const char* dbpath) {
init ((Xapian::Database(dbpath)));
}
_MuQuery (Xapian::Database* db) {
init (*db);
}
void init (Xapian::Database db) {
_db = db;
_qparser.set_database (_db);
_qparser.set_default_op (Xapian::Query::OP_AND);
_qparser.add_valuerangeprocessor (&_date_range_processor);
_qparser.add_valuerangeprocessor (&_size_range_processor);
mu_msg_field_foreach ((MuMsgFieldForEachFunc)add_prefix,
&_qparser);
}
Xapian::Database _db;
Xapian::QueryParser _qparser;
MuDateRangeProcessor _date_range_processor;
@ -180,8 +188,8 @@ static const Xapian::Query
get_query (MuQuery *mqx, const char* searchexpr, GError **err)
{
Xapian::Query query;
char *preprocessed;
char *preprocessed;
preprocessed = mu_query_preprocess (searchexpr);
try {
@ -194,7 +202,7 @@ get_query (MuQuery *mqx, const char* searchexpr, GError **err)
Xapian::QueryParser::FLAG_BOOLEAN_ANY_CASE);
g_free (preprocessed);
return query;
} catch (...) {
/* some error occured */
g_set_error (err, 0, MU_ERROR_XAPIAN_QUERY,
@ -213,13 +221,13 @@ add_prefix (MuMsgFieldId mfid, Xapian::QueryParser* qparser)
!mu_msg_field_xapian_term(mfid) &&
!mu_msg_field_xapian_contact(mfid))
return;
try {
const std::string pfx
(1, mu_msg_field_xapian_prefix (mfid));
const std::string shortcut
(1, mu_msg_field_shortcut (mfid));
if (mu_msg_field_uses_boolean_prefix (mfid)) {
qparser->add_boolean_prefix
(mu_msg_field_name(mfid), pfx);
@ -229,8 +237,8 @@ add_prefix (MuMsgFieldId mfid, Xapian::QueryParser* qparser)
(mu_msg_field_name(mfid), pfx);
qparser->add_prefix (shortcut, pfx);
}
if (!mu_msg_field_needs_prefix(mfid))
if (!mu_msg_field_needs_prefix(mfid))
qparser->add_prefix ("", pfx);
} MU_XAPIAN_CATCH_BLOCK;
@ -240,33 +248,58 @@ MuQuery*
mu_query_new (const char* xpath, GError **err)
{
g_return_val_if_fail (xpath, NULL);
if (!mu_util_check_dir (xpath, TRUE, FALSE)) {
g_set_error (err, 0, MU_ERROR_XAPIAN_DIR_NOT_ACCESSIBLE,
"'%s' is not a readable xapian dir", xpath);
return NULL;
}
if (mu_util_xapian_needs_upgrade (xpath)) {
if (mu_store_database_needs_upgrade (xpath)) {
g_set_error (err, 0, MU_ERROR_XAPIAN_NOT_UP_TO_DATE,
"%s is not up-to-date, needs a full update",
xpath);
return NULL;
}
if (mu_util_xapian_is_empty (xpath))
if (mu_store_database_is_empty (xpath))
g_warning ("database %s is empty; nothing to do", xpath);
try {
return new MuQuery (xpath);
} MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN (err, MU_ERROR_XAPIAN, NULL);
} MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN (err, MU_ERROR_XAPIAN, NULL);
return 0;
}
MuQuery*
mu_query_new_from_store (MuStore *store, GError **err)
{
g_return_val_if_fail (store, NULL);
try {
XapianDatabase *db;
db = mu_store_get_read_only_database(store);
return new MuQuery (reinterpret_cast<Xapian::Database*>(db));
} MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN (err, MU_ERROR_XAPIAN, NULL);
return 0;
}
MuQuery *mu_query_new_from_store (MuStore *store, GError **err)
G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
void
mu_query_destroy (MuQuery *self)
{
@ -282,13 +315,13 @@ mu_query_preprocess (const char *query)
g_return_val_if_fail (query, NULL);
my_query = g_strdup (query);
/* remove accents and turn to lower-case */
mu_str_normalize_in_place (my_query, TRUE);
/* escape '@', single '_' and ':' if it's not following a
* xapian-pfx with '_' */
mu_str_ascii_xapian_escape_in_place (my_query);
return my_query;
}
@ -296,10 +329,10 @@ mu_query_preprocess (const char *query)
MuMsgIter*
mu_query_run (MuQuery *self, const char* searchexpr, gboolean threads,
MuMsgFieldId sortfieldid, gboolean ascending,
GError **err)
GError **err)
{
g_return_val_if_fail (self, NULL);
g_return_val_if_fail (searchexpr, NULL);
g_return_val_if_fail (searchexpr, NULL);
g_return_val_if_fail (mu_msg_field_id_is_valid (sortfieldid) ||
sortfieldid == MU_MSG_FIELD_ID_NONE,
NULL);
@ -319,25 +352,25 @@ mu_query_run (MuQuery *self, const char* searchexpr, gboolean threads,
enq.set_cutoff(0,0);
return mu_msg_iter_new (
(XapianEnquire*)&enq,
self->_db.get_doccount(), threads,
threads ? sortfieldid : MU_MSG_FIELD_ID_NONE);
} MU_XAPIAN_CATCH_BLOCK_RETURN(NULL);
}
char*
mu_query_as_string (MuQuery *self, const char *searchexpr, GError **err)
mu_query_as_string (MuQuery *self, const char *searchexpr, GError **err)
{
g_return_val_if_fail (self, NULL);
g_return_val_if_fail (searchexpr, NULL);
try {
Xapian::Query query (get_query(self, searchexpr, err));
Xapian::Query query (get_query(self, searchexpr, err));
return g_strdup(query.get_description().c_str());
} MU_XAPIAN_CATCH_BLOCK_RETURN(NULL);
}

View File

@ -21,8 +21,9 @@
#define __MU_QUERY_H__
#include <glib.h>
#include <mu-store.h>
#include <mu-msg-iter.h>
#include <mu-util.h> /* for MuResult, MuError */
#include <mu-util.h>
G_BEGIN_DECLS
@ -45,6 +46,25 @@ typedef struct _MuQuery MuQuery;
MuQuery *mu_query_new (const char* path, GError **err)
G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
/**
* create a new MuQuery instance using an existing MuStore
*
* @param store a valid MuStore object
* @param err receives error information (if there is any); if
* function returns non-NULL, err will _not_be set. err can be NULL
* possble errors (err->code) are MU_ERROR_XAPIAN_DIR and
* MU_ERROR_XAPIAN_NOT_UPTODATE
*
* @return a new MuQuery instance, or NULL in case of error.
* when the instance is no longer needed, use mu_query_destroy
* to free it
*/
MuQuery *mu_query_new_from_store (MuStore *store, GError **err)
G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
/**
* destroy the MuQuery instance
*

View File

@ -33,7 +33,7 @@ G_BEGIN_DECLS
* do system-specific initialization. should be called before anything
* else. Initializes the locale and Gtype. Note: this function is
* called by mu_runtime_init.
*
*
* @return TRUE if is succeeds, FALSE otherwise
*/
gboolean mu_util_init_system (void);
@ -43,7 +43,7 @@ gboolean mu_util_init_system (void);
* path does not have to exist
*
* @param path path to expand
*
*
* @return the expanded path as a newly allocated string, or NULL in
* case of error
*/
@ -53,7 +53,7 @@ char* mu_util_dir_expand (const char* path)
/**
* guess the maildir; first try $MAILDIR; if it is unset or
* non-existant, try ~/Maildir if both fail, return NULL
*
*
* @return full path of the guessed Maildir, or NULL; must be freed (gfree)
*/
char* mu_util_guess_maildir (void)
@ -64,7 +64,7 @@ char* mu_util_guess_maildir (void)
* guess the place of the mu homedir (typically, ~/.mu). Note, this
* directory does not necessarily exist. mu_util_check_dir can be use
* to check that
*
*
* @return the guessed mu homedir, which needs to be freed with g_free
* when no longer needed.
*/
@ -74,11 +74,11 @@ gchar* mu_util_guess_mu_homedir (void)
/**
* if path exists, check that's a read/writeable dir; otherwise try to
* create it (with perms 0700)
*
*
* @param path path to the dir
* @param mode to set for the dir (as per chmod(1))
* @param nowarn, if TRUE, don't write warnings (if any) to stderr
*
*
* @return TRUE if a read/writeable directory `path' exists after
* leaving this function, FALSE otherwise
*/
@ -88,11 +88,11 @@ gboolean mu_util_create_dir_maybe (const gchar *path, mode_t mode, gboolean nowa
/**
* check whether path is a directory, and optionally, if it's readable
* and/or writeable
*
*
* @param path dir path
* @param readable check for readability
* @param writeable check for writability
*
*
* @return TRUE if dir exist and has the specified properties
*/
gboolean mu_util_check_dir (const gchar* path, gboolean readable,
@ -102,8 +102,8 @@ gboolean mu_util_check_dir (const gchar* path, gboolean readable,
/**
* get our the cache directory, typically, /tmp/mu-<userid>/
*
* @return the cache directory; don't free
*
* @return the cache directory; don't free
*/
const char* mu_util_cache_dir (void) G_GNUC_CONST;
@ -112,11 +112,11 @@ const char* mu_util_cache_dir (void) G_GNUC_CONST;
/**
* create a writeable file and return its file descriptor (which
* you'll need to close(2) when done with it.)
*
*
* @param path the full path of the file to create
* @param the mode to open (ie. 0644 or 0600 etc., see chmod(3)
* @param overwrite should we allow for overwriting existing files?
*
*
* @return a file descriptor, or -1 in case of error. If it's a file
* system error, 'errno' may contain more info. use 'close()' when done
* with the file descriptor
@ -129,17 +129,17 @@ int mu_util_create_writeable_fd (const char* path, mode_t mode,
/**
* check if file is local, ie. on the local file system. this means
* that it's either having a file URI, *or* that it's an existing file
*
*
* @param path a path
*
*
* @return TRUE if the file is local, FALSE otherwise
*/
gboolean mu_util_is_local_file (const char* path);
/**
* is the current locale utf-8 compatible?
*
* is the current locale utf-8 compatible?
*
* @return TRUE if it's utf8 compatible, FALSE otherwise
*/
gboolean mu_util_locale_is_utf8 (void) G_GNUC_CONST;
@ -148,10 +148,10 @@ gboolean mu_util_locale_is_utf8 (void) G_GNUC_CONST;
/**
* write a string (assumed to be in utf8-format) to a stream,
* converted to the current locale
*
*
* @param str a string
* @param stream a stream
*
*
* @return TRUE if printing worked, FALSE otherwise
*/
gboolean mu_util_fputs_encoded (const char *str, FILE *stream);
@ -159,9 +159,9 @@ gboolean mu_util_fputs_encoded (const char *str, FILE *stream);
/**
* print a formatted string (assumed to be in utf8-format) to stdout,
* converted to the current locale
*
*
* @param a standard printf() format string, followed by a parameter list
*
*
* @return TRUE if printing worked, FALSE otherwise
*/
gboolean mu_util_print_encoded (const char *frm, ...) G_GNUC_PRINTF(1,2);
@ -169,9 +169,9 @@ gboolean mu_util_print_encoded (const char *frm, ...) G_GNUC_PRINTF(1,2);
/**
* print a formatted string (assumed to be in utf8-format) to stderr,
* converted to the current locale
*
*
* @param a standard printf() format string, followed by a parameter list
*
*
* @return TRUE if printing worked, FALSE otherwise
*/
gboolean mu_util_printerr_encoded (const char *frm, ...) G_GNUC_PRINTF(1,2);
@ -181,82 +181,23 @@ gboolean mu_util_printerr_encoded (const char *frm, ...) G_GNUC_PRINTF(1,2);
/**
* try to 'play' (ie., open with it's associated program) a
* file. depends on xdg-open to do the actual opening
*
*
* @param path full path of the file to open
* @param allow_local allow local files (ie. with file:// prefix or fs paths)
* @param allow_remote allow URIs (ie., http, mailto)
*
*
* @return TRUE if it succeeded, FALSE otherwise
*/
gboolean mu_util_play (const char *path,
gboolean allow_local, gboolean allow_remote);
/**
" * get the version of the xapian database (ie., the version of the
* 'schema' we are using). If this version != MU_XAPIAN_DB_VERSION,
* it's means we need to a full reindex.
*
* @param xpath path to the xapian database
*
* @return the version of the database as a newly allocated string
* (free with g_free); if there is no version yet, it will return NULL
*/
gchar* mu_util_xapian_dbversion (const gchar *xpath) G_GNUC_WARN_UNUSED_RESULT;
/**
* check whether the database needs to be upgraded, e.g., when it was
* created with a different version of mu
*
* @param xpath path to the database dir
*
* @return TRUE if the database needs upgrading, FALSE otherwise
*/
gboolean mu_util_xapian_needs_upgrade (const gchar *xpath);
/**
* check whether the database is empty (contains 0 documents); in
* addition, a non-existing database is considered 'empty' too
*
* @param xpath path to the xapian database
*
* @return TRUE if the database is empty, FALSE otherwise
*/
gboolean mu_util_xapian_is_empty (const gchar *xpath);
/**
* clear the database, ie., remove all of the contents. This is a
* destructive operation, but the database can be restored be doing a
* full scan of the maildirs. Also, clear the contacts cache file
*
* @param xpath path to the database
* @param ccache path to the contacts cache file
*
* @return TRUE if the clearing succeeded, FALSE otherwise.
*/
gboolean mu_util_xapian_clear (const gchar *xpath,
const gchar *ccache);
/**
* check if the database is locked for writing
*
* @param xpath path to a xapian database
*
* @return TRUE if it is locked, FALSE otherwise (or in case of error)
*/
gboolean mu_util_xapian_is_locked (const gchar *xpath);
/**
* convert a string array in to a string, with the elements separated
* by ' '
*
*
* @param params a non-NULL, NULL-terminated string array
*
*
* @return a newly allocated string
*/
gchar* mu_util_str_from_strv (const gchar **params)
@ -292,9 +233,9 @@ enum {
/**
* get the d_type (as in direntry->d_type) for the file at path, using
* lstat(3)
*
*
* @param path full path
*
*
* @return DT_REG, DT_DIR, DT_LNK, or DT_UNKNOWN (other values are not
* supported currently )
*/
@ -303,20 +244,23 @@ unsigned char mu_util_get_dtype_with_lstat (const char *path);
/**
* we need this when using Xapian::Document* from C
*
*
*/
typedef gpointer XapianDocument;
/**
* we need this when using Xapian::Enquire* from C
*
*
*/
typedef gpointer XapianEnquire;
/**
*
*
* don't repeat these catch blocks everywhere...
*
*
*/
#define MU_XAPIAN_CATCH_BLOCK \
catch (const Xapian::Error &xerr) { \
@ -396,13 +340,13 @@ typedef gpointer XapianEnquire;
enum _MuError {
/* no error at all! */
MU_OK = 0,
/* generic error */
MU_ERROR = 1,
MU_ERROR_IN_PARAMETERS = 2,
MU_ERROR_INTERNAL = 3,
MU_ERROR_INTERNAL = 3,
MU_ERROR_NO_MATCHES = 4,
/* general xapian related error */
MU_ERROR_XAPIAN = 11,
@ -420,15 +364,15 @@ enum _MuError {
MU_ERROR_XAPIAN_CANNOT_GET_WRITELOCK = 18,
/* GMime related errors */
/* gmime parsing related error */
MU_ERROR_GMIME = 30,
/* contacts related errors */
MU_ERROR_CONTACTS = 50,
MU_ERROR_CONTACTS_CANNOT_RETRIEVE = 51,
/* File errors */
/* generic file-related error */
MU_ERROR_FILE = 70,
@ -442,7 +386,7 @@ enum _MuError {
MU_ERROR_FILE_READDIR_FAILED = 78,
MU_ERROR_FILE_INVALID_SOURCE = 79,
MU_ERROR_FILE_TARGET_EQUALS_SOURCE = 80,
/* not really an error, used in callbacks */
MU_STOP = 99,
};