From fbc786f2fc40355984653380304a390c58d08121 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Mon, 29 Aug 2011 23:38:55 +0300 Subject: [PATCH] * minor changes, trailing whitespace fixes --- src/mu-cmd-find.c | 194 ++++++++++++++++++++++----------------------- src/mu-cmd-index.c | 93 +++++++++++----------- src/mu-cmd.c | 107 +++++++++++++------------ src/mu-cmd.h | 63 +++++++++------ src/mu-index.c | 127 +++++++++++++++-------------- src/mu-msg-sexp.c | 2 +- src/mu-msg.c | 151 ++++++++++++++++++----------------- src/mu-query.cc | 135 +++++++++++++++++++------------ src/mu-query.h | 22 ++++- src/mu-util.h | 140 ++++++++++---------------------- 10 files changed, 528 insertions(+), 506 deletions(-) diff --git a/src/mu-cmd-find.c b/src/mu-cmd-find.c index 3d79349e..47b371a9 100644 --- a/src/mu-cmd-find.c +++ b/src/mu-cmd-find.c @@ -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 : ""); 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\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 ("\n"); g_print ("\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 ("\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) diff --git a/src/mu-cmd-index.c b/src/mu-cmd-index.c index 7a12af37..157fc100 100644 --- a/src/mu-cmd-index.c +++ b/src/mu-cmd-index.c @@ -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); } diff --git a/src/mu-cmd.c b/src/mu-cmd.c index 7231d7fe..a63f01bb 100644 --- a/src/mu-cmd.c +++ b/src/mu-cmd.c @@ -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] []"); 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 : ""); 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=] " " [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; } + + + diff --git a/src/mu-cmd.h b/src/mu-cmd.h index 3ddf540f..7ef017f8 100644 --- a/src/mu-cmd.h +++ b/src/mu-cmd.h @@ -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__*/ diff --git a/src/mu-index.c b/src/mu-index.c index c90a9fa8..92a8d658 100644 --- a/src/mu-index.c +++ b/src/mu-index.c @@ -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 ** ** 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); diff --git a/src/mu-msg-sexp.c b/src/mu-msg-sexp.c index fc2e7ed7..83e23505 100644 --- a/src/mu-msg-sexp.c +++ b/src/mu-msg-sexp.c @@ -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); } diff --git a/src/mu-msg.c b/src/mu-msg.c index 45a944d3..096ba03a 100644 --- a/src/mu-msg.c +++ b/src/mu-msg.c @@ -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 @@ -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; } diff --git a/src/mu-query.cc b/src/mu-query.cc index 439fd3b1..5acc1fac 100644 --- a/src/mu-query.cc +++ b/src/mu-query.cc @@ -1,20 +1,20 @@ -/* +/* ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema ** ** 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 @@ -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(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); } diff --git a/src/mu-query.h b/src/mu-query.h index a93faa07..059e5911 100644 --- a/src/mu-query.h +++ b/src/mu-query.h @@ -21,8 +21,9 @@ #define __MU_QUERY_H__ #include +#include #include -#include /* for MuResult, MuError */ +#include 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 * diff --git a/src/mu-util.h b/src/mu-util.h index acbaaf65..2f5b9095 100644 --- a/src/mu-util.h +++ b/src/mu-util.h @@ -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-/ - * - * @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, };