diff --git a/src/Makefile.am b/src/Makefile.am index 7cb7b231..edda38b8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,8 +25,6 @@ mu_SOURCES= \ mu-msg-xapian-priv.hh \ mu-msg-xapian.cc \ mu-msg-xapian.h \ - mu-query.h \ - mu-query.c \ mu-query-xapian.cc \ mu-query-xapian.h \ mu-result.h \ diff --git a/src/mu-cmd.c b/src/mu-cmd.c index c741fd10..c4bd9f6d 100644 --- a/src/mu-cmd.c +++ b/src/mu-cmd.c @@ -17,11 +17,22 @@ ** */ +#include + +#include +#include #include + +#include "mu-msg-gmime.h" +#include "mu-maildir.h" +#include "mu-index.h" +#include "mu-query-xapian.h" +#include "mu-msg-xapian.h" +#include "mu-msg-str.h" #include "mu-cmd.h" -MuCmd -mu_cmd_from_string (const char* cmd) +static MuCmd +_cmd_from_string (const char* cmd) { if (!cmd) return MU_CMD_UNKNOWN; @@ -50,12 +61,193 @@ mu_cmd_from_string (const char* cmd) } +static gboolean +_print_query (MuQueryXapian *xapian, const gchar *query) +{ + char *querystr; + + querystr = mu_query_xapian_as_string (xapian, query); + g_print ("%s\n", querystr); + g_free (querystr); + + return TRUE; +} + + +static const gchar* +_display_field (MuMsgXapian *row, const MuMsgField* field) +{ + gint64 val; + + switch (mu_msg_field_type(field)) { + case MU_MSG_FIELD_TYPE_STRING: + return mu_msg_xapian_get_field (row, field); + + case MU_MSG_FIELD_TYPE_INT: + + if (mu_msg_field_id(field) == MU_MSG_FIELD_ID_PRIORITY) { + val = mu_msg_xapian_get_field_numeric (row, field); + return mu_msg_str_prio ((MuMsgPriority)val); + } + + if (mu_msg_field_id(field) == MU_MSG_FIELD_ID_FLAGS) { + val = mu_msg_xapian_get_field_numeric (row, field); + return mu_msg_str_flags_s ((MuMsgPriority)val); + } + + return mu_msg_xapian_get_field (row, field); /* as string */ + case MU_MSG_FIELD_TYPE_TIME_T: + val = mu_msg_xapian_get_field_numeric (row, field); + return mu_msg_str_date_s ((time_t)val); + case MU_MSG_FIELD_TYPE_BYTESIZE: + val = mu_msg_xapian_get_field_numeric (row, field); + return mu_msg_str_size_s ((time_t)val); + default: + g_return_val_if_reached (NULL); + } +} + + +/* returns NULL if there is an error */ +const MuMsgField* +_sort_field_from_string (const char* fieldstr) +{ + const MuMsgField *field; + + field = mu_msg_field_from_name (fieldstr); + if (!field && strlen(fieldstr) == 1) + field = mu_msg_field_from_shortcut(fieldstr[0]); + if (!field) + g_printerr ("not a valid sort field: '%s'\n", + fieldstr); + return field; +} + + + + +static gboolean +_print_rows (MuQueryXapian *xapian, const gchar *query, MuConfigOptions *opts) +{ + MuMsgXapian *row; + const MuMsgField *sortfield; + + sortfield = NULL; + if (opts->sortfield) { + sortfield = _sort_field_from_string (opts->sortfield); + if (!sortfield) /* error occured? */ + return FALSE; + } + + row = mu_query_xapian_run (xapian, query, sortfield, + !opts->descending); + if (!row) { + g_printerr ("error: running query failed\n"); + return FALSE; + } + + /* iterate over the found rows */ + while (!mu_msg_xapian_is_done (row)) { + const char* fields = opts->fields; + int printlen = 0; + while (*fields) { + const MuMsgField* field = + mu_msg_field_from_shortcut (*fields); + if (!field || + !mu_msg_field_is_xapian_enabled (field)) + printlen += printf ("%c", *fields); + else + printlen += printf ("%s", + _display_field(row, field)); + ++fields; + } + if (printlen >0) + printf ("\n"); + + mu_msg_xapian_next (row); + } + + mu_msg_xapian_destroy (row); + return TRUE; +} + + +static gboolean +_do_output_text (MuQueryXapian *xapian, MuConfigOptions* opts, + const gchar **params) +{ + gchar *query; + gboolean retval = TRUE; + + query = mu_query_xapian_combine (params, FALSE); + + /* if xquery is set, we print the xapian query instead of the + * output; this is for debugging purposes */ + if (opts->xquery) + retval = _print_query (xapian, query); + else + retval = _print_rows (xapian, query, opts); + + g_free (query); + + return retval; +} + +static gboolean +_create_linkdir_if_nonexistant (const gchar* linkdir) +{ + if (access (linkdir, F_OK) != 0) + if (!mu_maildir_mkmdir (linkdir, 0700, TRUE)) + return FALSE; + + return TRUE; +} + +static gboolean +_do_output_links (MuQueryXapian *xapian, MuConfigOptions* opts, + const gchar **params) +{ + gchar *query; + gboolean retval = TRUE; + MuMsgXapian *row; + const MuMsgField *pathfield; + + if (!_create_linkdir_if_nonexistant (opts->linksdir)) + return FALSE; + + query = mu_query_xapian_combine (params, FALSE); + row = mu_query_xapian_run (xapian, query, NULL, FALSE); + if (!row) { + g_printerr ("error: running query failed\n"); + return FALSE; + } + + pathfield = mu_msg_field_from_id (MU_MSG_FIELD_ID_PATH); + + /* iterate over the found rows */ + while (!mu_msg_xapian_is_done (row)) { + const char *path; + path = mu_msg_xapian_get_field (row, pathfield); + if (path) { + retval = mu_maildir_link (path, opts->linksdir); + if (!retval) + break; + } + mu_msg_xapian_next (row); + } + + mu_msg_xapian_destroy (row); + g_free (query); + + return retval; +} + static gboolean _check_query_params (MuConfigOptions *opts) { if (opts->linksdir) - if (opts->fields || opts->sortfield || opts->xquery) { + if (opts->xquery) { g_warning ("Invalid option for '--linksdir'"); return FALSE; } @@ -65,13 +257,7 @@ _check_query_params (MuConfigOptions *opts) g_warning ("Invalid option for '--xquery'"); return FALSE; } - - if (opts->ascending && opts->descending) { - g_warning ("Cannot specify both '--ascending'" - " and '--descending'"); - return FALSE; - } - + if (!opts->params[0] || !opts->params[1]) { g_warning ("Missing search expression"); return FALSE; @@ -81,14 +267,48 @@ _check_query_params (MuConfigOptions *opts) } + +gboolean +_cmd_query (MuConfigOptions *opts) +{ + MuQueryXapian *xapian; + gboolean rv; + const gchar **params; + + if (!_check_query_params (opts)) + return FALSE; + + /* first param is 'query', search params are after that */ + params = (const gchar**)&opts->params[1]; + + mu_msg_gmime_init(); + + xapian = mu_query_xapian_new (opts->muhome); + if (!xapian) { + mu_msg_gmime_uninit (); + return FALSE; + } + + if (opts->linksdir) + rv = _do_output_links (xapian, opts, params); + else + rv = _do_output_text (xapian, opts, params); + + mu_query_xapian_destroy (xapian); + mu_msg_gmime_uninit(); + + return rv; +} + + + static gboolean _check_index_params (MuConfigOptions *opts) { if (opts->linksdir) if (opts->linksdir || opts->fields || opts->sortfield || opts->xquery || - opts->ascending || opts->descending|| - opts->xquery) { + opts->descending|| opts->xquery) { g_warning ("Invalid option(s) for command"); return FALSE; } @@ -97,18 +317,165 @@ _check_index_params (MuConfigOptions *opts) } +static MuResult +_msg_cb (MuIndexStats* stats, void *user_data) +{ + char *kars="-\\|/"; + char output[100]; + + static int i = 0; + static int len = 0; + + while (len --> 0) + printf ("\b"); + + len = snprintf (output, sizeof(output), + "%c mu is indexing your mails; processed: %d; " + "updated/new: %d", + kars[i % 4], stats->_processed, stats->_updated); + g_print ("%s", output); + + ++i; + + return MU_OK; +} + + +static gboolean +_cmd_index (MuConfigOptions *opts) +{ + MuIndex *midx; + MuIndexStats stats; + int rv; + + if (!_check_index_params (opts)) + return FALSE; + + mu_msg_gmime_init (); + { + midx = mu_index_new (opts->muhome); + rv = mu_index_run (midx, + opts->maildir, + opts->reindex, + &stats, + opts->quiet ? NULL : _msg_cb, + NULL, + NULL); + g_print ("\n"); + mu_index_destroy (midx); + } + mu_msg_gmime_uninit (); + + return rv == MU_OK ? TRUE : FALSE; +} + + +static int +_cmd_mkdir (MuConfigOptions *opts) +{ + int i; + + if (!opts->params[0]) + return FALSE; /* shouldn't happen */ + + if (!opts->params[1]) { + g_printerr ("usage: mu mkdir [more dirs]\n"); + return FALSE; + } + + i = 1; + while (opts->params[i]) { + if (!mu_maildir_mkmdir (opts->params[i], 0755, FALSE)) + return FALSE; + ++i; + } + + return TRUE; +} + + + +static gboolean +_cmd_link (MuConfigOptions *opts) +{ + if (!opts->params[0]) + return FALSE; /* shouldn't happen */ + + if (!opts->params[1] || !opts->params[2]) { + g_printerr ("usage: mu link \n"); + return FALSE; + } + + return mu_maildir_link (opts->params[1], opts->params[2]); +} + + + +static gboolean +_show_usage (gboolean noerror) +{ + const char* usage= + "usage: mu [options] command [parameters]\n" + "\twhere command is one of index, query, help\n" + "see mu(1) for for information\n"; + + if (noerror) + g_print ("%s", usage); + else + g_printerr ("%s", usage); + + return noerror; +} + +static gboolean +_show_version (void) +{ + const char* msg = + "mu (mail indexer / searcher version) " VERSION "\n\n" + "Copyright (C) 2010 Dirk-Jan C. Binnema\n" + "License GPLv3+: GNU GPL version 3 or later " + ".\n\n" + "This is free software: you are free to change " + "and redistribute it.\n" + "There is NO WARRANTY, to the extent permitted by law."; + + g_print ("%s\n", msg); + + return TRUE; +} + + +static gboolean +_cmd_help (MuConfigOptions *opts) +{ + /* FIXME: get context-sensitive help */ + _show_version (); + return _show_usage (FALSE); +} + + gboolean -mu_cmd_check_parameters (MuCmd cmd, MuConfigOptions *opts) +mu_cmd_execute (MuConfigOptions *opts) { - g_return_val_if_fail (cmd > 0 && cmd < MU_CMD_UNKNOWN, - FALSE); + MuCmd cmd; + + if (opts->version) + return _show_version (); + + if (!opts->params||!opts->params[0]) /* no command? */ + return _show_usage (FALSE); + + cmd = _cmd_from_string (opts->params[0]); + switch (cmd) { - case MU_CMD_INDEX: - return _check_index_params (opts); - case MU_CMD_QUERY: - return _check_query_params (opts); + case MU_CMD_UNKNOWN: return _show_usage (FALSE); + case MU_CMD_HELP: return _cmd_help (opts); + case MU_CMD_MKDIR: return _cmd_mkdir (opts); + case MU_CMD_LINK: return _cmd_link (opts); + case MU_CMD_INDEX: return _cmd_index (opts); + case MU_CMD_QUERY: return _cmd_query (opts); default: - return TRUE; - } + g_return_val_if_reached (FALSE); + } } diff --git a/src/mu-cmd.h b/src/mu-cmd.h index 37191257..b250c027 100644 --- a/src/mu-cmd.h +++ b/src/mu-cmd.h @@ -24,6 +24,8 @@ #include #include "mu-config.h" +G_BEGIN_DECLS + enum _MuCmd { MU_CMD_INDEX, MU_CMD_QUERY, @@ -36,24 +38,14 @@ enum _MuCmd { typedef enum _MuCmd MuCmd; /** - * determine the Mu command from a string - * (as given on the cmdline) + * try to execute whatever is specified on the command line * - * @param cmd string for a command + * @param config a config structure with the command line params * - * @return the MuCmd or MU_CMD_UNKNOWN + * @return TRUE if it succeeded, FALSE otherwise */ -MuCmd mu_cmd_from_string (const char* cmd); +gboolean mu_cmd_execute (MuConfigOptions *config); - -/** - * check the command line parameters - * - * @param cmd the command - * @param opts options - * - * @return TRUE if there are no errors, FALSE otherwise - */ -gboolean mu_cmd_check_parameters (MuCmd cmd, MuConfigOptions *opts); +G_END_DECLS #endif /*__MU_CMD_H__*/ diff --git a/src/mu-config.c b/src/mu-config.c index 3d48c3d9..9fd8c6ea 100644 --- a/src/mu-config.c +++ b/src/mu-config.c @@ -39,9 +39,6 @@ mu_config_options_group_mu (MuConfigOptions *opts) "mu directory", NULL}, {"log-stderr", 'e', 0, G_OPTION_ARG_NONE, &opts->log_stderr, "log to standard error", NULL}, - {"log-append", 'a', 0, G_OPTION_ARG_NONE, &opts->log_append, - "append to the logfile (instead of overwriting)", - NULL}, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &opts->params, "parameters", NULL }, { NULL, 0, 0, 0, NULL, NULL, NULL } @@ -88,10 +85,8 @@ mu_config_options_group_query (MuConfigOptions *opts) "fields to display in the output", NULL}, {"sortfield", 's', 0, G_OPTION_ARG_STRING, &opts->sortfield, "field to sort on", NULL}, - {"ascending", 'u', 0, G_OPTION_ARG_NONE, &opts->ascending, - "sort ascending (up)", NULL}, {"descending", 'd', 0, G_OPTION_ARG_NONE, &opts->descending, - "sort descending (down)", NULL}, + "sort descending", NULL}, {"linksdir", 't', 0, G_OPTION_ARG_STRING, &opts->linksdir, "output as symbolic links to a target maildir", NULL }, { NULL, 0, 0, 0, NULL, NULL, NULL } @@ -113,29 +108,36 @@ mu_config_init (MuConfigOptions *opts) /* start from zero */ memset (opts, 0, sizeof(MuConfigOptions)); +} - /* general */ - opts->quiet = FALSE; - opts->debug = FALSE; - opts->muhome = mu_util_dir_expand ("~/.mu"); - opts->log_append = TRUE; +void +mu_config_set_defaults (MuConfigOptions *opts) +{ + g_return_if_fail (opts); + + if (!opts->muhome) + opts->muhome = mu_util_dir_expand ("~/.mu"); + opts->log_stderr = FALSE; /* indexing */ - opts->maildir = mu_util_guess_maildir(); - opts->cleanup = FALSE; - opts->reindex = FALSE; + if (!opts->maildir) + opts->maildir = mu_util_guess_maildir(); /* querying */ - opts->xquery = FALSE; - opts->fields = "d f s"; - opts->sortfield = "d"; - opts->ascending = FALSE; - opts->descending = TRUE; - opts->linksdir = NULL; + + /* note, when no fields are specified, we use + * date-from-subject, and sort descending by date. If fiels + * *are* specified, we sort in ascending order. */ + if (!opts->fields) { + opts->descending = TRUE; + opts->fields = "d f s"; + opts->sortfield = "d"; + } } + void mu_config_uninit (MuConfigOptions *opts) { diff --git a/src/mu-config.h b/src/mu-config.h index 9f78efe8..e0979a1e 100644 --- a/src/mu-config.h +++ b/src/mu-config.h @@ -23,6 +23,8 @@ #include #include "mu-msg-fields.h" +G_BEGIN_DECLS + /* struct with all configuration options for mu; it will be filled * from the config file, and/or command line arguments */ @@ -34,7 +36,6 @@ struct _MuConfigOptions { char *muhome; /* the House of Mu */ gboolean version; /* request mu version */ gboolean log_stderr; /* log to stderr (not logfile) */ - gboolean log_append; /* append to log (don't overwrite)*/ gchar** params; /* parameters (for querying) */ /* options for indexing */ @@ -51,7 +52,6 @@ struct _MuConfigOptions { char *linksdir; /* maildir to output symlinks */ gboolean descending; /* sort descending? */ - gboolean ascending; }; typedef struct _MuConfigOptions MuConfigOptions; @@ -65,6 +65,12 @@ typedef struct _MuConfigOptions MuConfigOptions; */ void mu_config_init (MuConfigOptions *opts); +/** + * fill unset config options with defaults + * + * @param opts options + */ +void mu_config_set_defaults (MuConfigOptions *opts); /** * free the MuOptionsCOnfig structure; the the muhome and maildir @@ -110,4 +116,6 @@ GOptionGroup* mu_config_options_group_query (MuConfigOptions *opts); */ char* mu_config_expanded_mu_home (MuConfigOptions *opts); +G_END_DECLS + #endif /*__MU_CONFIG_H__*/ diff --git a/src/mu-query-xapian.cc b/src/mu-query-xapian.cc index 2af85d36..f9bec561 100644 --- a/src/mu-query-xapian.cc +++ b/src/mu-query-xapian.cc @@ -218,8 +218,9 @@ mu_query_xapian_as_string (MuQueryXapian *self, const char* searchexpr) return NULL; } + char* -mu_query_xapian_combine (gchar **params, gboolean connect_or) +mu_query_xapian_combine (const gchar **params, gboolean connect_or) { GString *str; int i; diff --git a/src/mu-query-xapian.h b/src/mu-query-xapian.h index 7c7666d7..98e5b580 100644 --- a/src/mu-query-xapian.h +++ b/src/mu-query-xapian.h @@ -24,8 +24,6 @@ #include "mu-msg-xapian.h" G_BEGIN_DECLS - - /* * MuQueryXapian */ @@ -79,7 +77,7 @@ MuMsgXapian* mu_query_xapian_run (MuQueryXapian *self, * @return a string with the combined xapian expression or NULL in * case of error; free with g_free when it's no longer needed */ -char* mu_query_xapian_combine (gchar **params, gboolean connect_or); +char* mu_query_xapian_combine (const gchar **params, gboolean connect_or); /** * get a string representation of the Xapian search query diff --git a/src/mu-query.c b/src/mu-query.c deleted file mode 100644 index 8ef7d946..00000000 --- a/src/mu-query.c +++ /dev/null @@ -1,248 +0,0 @@ -/* -** Copyright (C) 2010 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. -** -*/ - -#include -#include -#include -#include -#include - -#include "mu-util.h" -#include "mu-result.h" -#include "mu-msg-str.h" -#include "mu-msg-flags.h" -#include "mu-query-xapian.h" -#include "mu-query.h" -#include "mu-maildir.h" - -static gboolean -print_query (MuQueryXapian *xapian, const gchar *query) -{ - char *querystr; - - querystr = mu_query_xapian_as_string (xapian, query); - g_print ("%s\n", querystr); - g_free (querystr); - - return TRUE; -} - - -static const gchar* -display_field (MuMsgXapian *row, const MuMsgField* field) -{ - gint64 val; - - switch (mu_msg_field_type(field)) { - case MU_MSG_FIELD_TYPE_STRING: - return mu_msg_xapian_get_field (row, field); - - case MU_MSG_FIELD_TYPE_INT: - - if (mu_msg_field_id(field) == MU_MSG_FIELD_ID_PRIORITY) { - val = mu_msg_xapian_get_field_numeric (row, field); - return mu_msg_str_prio ((MuMsgPriority)val); - } - - if (mu_msg_field_id(field) == MU_MSG_FIELD_ID_FLAGS) { - val = mu_msg_xapian_get_field_numeric (row, field); - return mu_msg_str_flags_s ((MuMsgPriority)val); - } - - return mu_msg_xapian_get_field (row, field); /* as string */ - case MU_MSG_FIELD_TYPE_TIME_T: - val = mu_msg_xapian_get_field_numeric (row, field); - return mu_msg_str_date_s ((time_t)val); - case MU_MSG_FIELD_TYPE_BYTESIZE: - val = mu_msg_xapian_get_field_numeric (row, field); - return mu_msg_str_size_s ((time_t)val); - default: - g_return_val_if_reached (NULL); - } -} - - -/* returns NULL if there is an error */ -const MuMsgField* -sort_field_from_string (const char* fieldstr) -{ - const MuMsgField *field; - - field = mu_msg_field_from_name (fieldstr); - if (!field && strlen(fieldstr) == 1) - field = mu_msg_field_from_shortcut(fieldstr[0]); - if (!field) - g_printerr ("not a valid sort field: '%s'\n", - fieldstr); - return field; -} - - -static gboolean -handle_options (MuConfigOptions *opts) -{ - if (opts->ascending && opts->descending) { - g_printerr ("only one of --ascending and --descending " - "may be specied\n"); - return FALSE; - } - - return opts->ascending = opts->descending ? FALSE : TRUE; -} - - -static gboolean -print_rows (MuQueryXapian *xapian, const gchar *query, MuConfigOptions *opts) -{ - MuMsgXapian *row; - const MuMsgField *sortfield; - - sortfield = NULL; - if (opts->sortfield) { - sortfield = sort_field_from_string (opts->sortfield); - if (!sortfield) /* error occured? */ - return FALSE; - } - - row = mu_query_xapian_run (xapian, query, - sortfield, - opts->ascending); - if (!row) { - g_printerr ("error: running query failed\n"); - return FALSE; - } - - /* iterate over the found rows */ - while (!mu_msg_xapian_is_done (row)) { - const char* fields = opts->fields; - int printlen = 0; - while (*fields) { - const MuMsgField* field = - mu_msg_field_from_shortcut (*fields); - if (!field || - !mu_msg_field_is_xapian_enabled (field)) - printlen += printf ("%c", *fields); - else - printlen += printf ("%s", - display_field(row, field)); - ++fields; - } - if (printlen >0) - printf ("\n"); - - mu_msg_xapian_next (row); - } - - mu_msg_xapian_destroy (row); - return TRUE; -} - - -static gboolean -_do_output_text (MuQueryXapian *xapian, MuConfigOptions* opts, gchar **params) -{ - gchar *query; - gboolean retval = TRUE; - - query = mu_query_xapian_combine (params, FALSE); - - /* if xquery is set, we print the xapian query instead of the - * output; this is for debugging purposes */ - if (opts->xquery) - retval = print_query (xapian, query); - else - retval = print_rows (xapian, query, opts); - - g_free (query); - - return retval; -} - -static gboolean -_create_linkdir_if_nonexistant (const gchar* linkdir) -{ - if (access (linkdir, F_OK) != 0) - if (!mu_maildir_mkmdir (linkdir, 0700, TRUE)) - return FALSE; - - return TRUE; -} - -static gboolean -_do_output_links (MuQueryXapian *xapian, MuConfigOptions* opts, gchar **params) -{ - gchar *query; - gboolean retval = TRUE; - MuMsgXapian *row; - const MuMsgField *pathfield; - - if (!_create_linkdir_if_nonexistant (opts->linksdir)) - return FALSE; - - query = mu_query_xapian_combine (params, FALSE); - row = mu_query_xapian_run (xapian, query, NULL, FALSE); - if (!row) { - g_printerr ("error: running query failed\n"); - return FALSE; - } - - pathfield = mu_msg_field_from_id (MU_MSG_FIELD_ID_PATH); - - /* iterate over the found rows */ - while (!mu_msg_xapian_is_done (row)) { - const char *path; - path = mu_msg_xapian_get_field (row, pathfield); - if (path) { - retval = mu_maildir_link (path, opts->linksdir); - if (!retval) - break; - } - mu_msg_xapian_next (row); - } - - mu_msg_xapian_destroy (row); - g_free (query); - - return retval; -} - - -MuResult -mu_query_run (MuConfigOptions *opts, gchar **params) -{ - MuQueryXapian *xapian; - MuResult rv; - - rv = MU_OK; - - handle_options (opts); - - xapian = mu_query_xapian_new (opts->muhome); - if (!xapian) - return MU_ERROR; - - if (opts->linksdir) - rv = _do_output_links (xapian, opts, params) ? 0 : 1; - else - rv = _do_output_text (xapian, opts, params) ? 0 : 1; - - mu_query_xapian_destroy (xapian); - - return rv; -} diff --git a/src/mu-query.h b/src/mu-query.h deleted file mode 100644 index 4c28d6d8..00000000 --- a/src/mu-query.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __MU_QUERY_H__ -#define __MU_QUERY_H__ - -#include "mu-config.h" - -MuResult mu_query_run (MuConfigOptions *opts, gchar **params); - -#endif /*__MU_QUERY_H__*/ - - - diff --git a/src/mu.c b/src/mu.c index 53ce266a..d17f4345 100644 --- a/src/mu.c +++ b/src/mu.c @@ -24,154 +24,15 @@ #include #include /* for fileno() */ -#include "mu-index.h" -#include "mu-query.h" -#include "mu-maildir.h" -#include "mu-util.h" #include "mu-config.h" #include "mu-cmd.h" #include "mu-log.h" -#include "mu-msg-gmime.h" - - -static MuResult -msg_cb (MuIndexStats* stats, void *user_data) -{ - char *kars="-\\|/"; - char output[100]; - - static int i = 0; - static int len = 0; - - while (len --> 0) - printf ("\b"); - - len = snprintf (output, sizeof(output), - "%c mu is indexing your mails; processed: %d; " - "updated/new: %d", - kars[i % 4], stats->_processed, stats->_updated); - g_print ("%s", output); - - ++i; - - return MU_OK; -} - - -static int -make_maildir (MuConfigOptions *opts) -{ - int i; - - if (!opts->params[0]) - return 1; /* shouldn't happen */ - - if (!opts->params[1]) { - g_printerr ("usage: mu mkdir [more dirs]\n"); - return 1; - } - - i = 1; - while (opts->params[i]) { - if (!mu_maildir_mkmdir (opts->params[i], 0755, FALSE)) - return 1; - ++i; - } - - return 0; -} - - - -static int -make_symlink (MuConfigOptions *opts) -{ - if (!opts->params[0]) - return 1; /* shouldn't happen */ - - if (!opts->params[1] || !opts->params[2]) { - g_printerr ("usage: mu link \n"); - return 1; - } - - return mu_maildir_link (opts->params[1], opts->params[2]) ? 0 : 1; -} - - - - -static int -show_usage (gboolean noerror) -{ - const char* usage= - "usage: mu [options] command [parameters]\n" - "\twhere command is one of index, query, help\n" - "see mu(1) for for information\n"; - - if (noerror) - g_print ("%s", usage); - else - g_printerr ("%s", usage); - - return noerror ? 0 : 1; -} - -static int -show_version (void) -{ - const char* msg = - "mu (mail indexer / searcher version) " VERSION "\n\n" - "Copyright (C) 2010 Dirk-Jan C. Binnema\n" - "License GPLv3+: GNU GPL version 3 or later " - ".\n\n" - "This is free software: you are free to change " - "and redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by law."; - - g_print ("%s\n", msg); - - return 0; -} - -static int -show_help (MuConfigOptions *opts) -{ - /* FIXME: get context-sensitive help */ - show_version (); - return show_usage (FALSE); -} - -static int -run_index (MuConfigOptions *opts) -{ - MuIndex *midx; - MuIndexStats stats; - int rv; - - midx = mu_index_new (opts->muhome); - rv = mu_index_run (midx, - opts->maildir, - opts->reindex, - &stats, - opts->quiet ? NULL : msg_cb, - NULL, - NULL); - g_print ("\n"); - mu_index_destroy (midx); - - return rv; -} - - - static gboolean init_log (MuConfigOptions *opts) { gboolean rv; - - /* TODO: check incompatible options (eg., silent + log_append) */ if (opts->quiet) rv = mu_log_init_silence (); @@ -179,8 +40,7 @@ init_log (MuConfigOptions *opts) rv = mu_log_init_with_fd (fileno(stderr), FALSE, opts->debug); else - rv = mu_log_init (opts->muhome, opts->log_append, - opts->debug); + rv = mu_log_init (opts->muhome, TRUE, opts->debug); if (!rv) g_print ("error: failed to initialize log\n"); @@ -188,75 +48,60 @@ init_log (MuConfigOptions *opts) return rv; } +static gboolean +_parse_params (MuConfigOptions *config, int *argcp, char ***argvp) +{ + GError *error = NULL; + GOptionContext *context; + gboolean rv; + + context = g_option_context_new ("- maildir utilities"); + + g_option_context_set_main_group (context, + mu_config_options_group_mu(config)); + g_option_context_add_group (context, + mu_config_options_group_index(config)); + g_option_context_add_group (context, + mu_config_options_group_query(config)); + + rv = g_option_context_parse (context, argcp, argvp, &error); + if (!rv) { + g_printerr ("error in options: %s\n", error->message); + g_error_free (error); + } else { + g_option_context_free (context); + mu_config_set_defaults (config); + } + + return rv; +} + int main (int argc, char *argv[]) { - GError *error = NULL; - GOptionContext *context; MuConfigOptions config; - MuResult rv; - MuCmd cmd; - gboolean ok; + gboolean rv; g_type_init (); - - context = g_option_context_new ("- maildir utilities"); - - g_option_context_set_main_group (context, - mu_config_options_group_mu(&config)); - g_option_context_add_group (context, - mu_config_options_group_index(&config)); - g_option_context_add_group (context, - mu_config_options_group_query(&config)); - mu_config_init (&config); - ok = g_option_context_parse (context, &argc, &argv, &error); - g_option_context_free (context); - - if (!init_log (&config)) - return 1; - - if (!ok) { - g_printerr ("error in options: %s\n", error->message); - g_error_free (error); + mu_config_init (&config); + + if (!_parse_params (&config, &argc, &argv)) { + mu_config_uninit (&config); return 1; } - if (config.version) - return show_version (); - - if (!config.params[0]) /* no command? */ - return show_usage (FALSE); - - cmd = mu_cmd_from_string (config.params[0]); - if (cmd == MU_CMD_UNKNOWN) - return show_usage (FALSE); - - if (!mu_cmd_check_parameters (cmd, &config)) + if (!init_log (&config)) { + mu_config_uninit (&config); return 1; - - if (cmd == MU_CMD_HELP) - return show_help (&config); + } + + rv = mu_cmd_execute (&config); - if (cmd == MU_CMD_MKDIR) - return make_maildir (&config); - - if (cmd == MU_CMD_LINK) - return make_symlink (&config); - - mu_msg_gmime_init (); - rv = MU_OK; - - if (cmd == MU_CMD_INDEX) - rv = run_index (&config); - else if (cmd == MU_CMD_QUERY) - rv = mu_query_run (&config, &config.params[1]); - - mu_msg_gmime_uninit(); mu_log_uninit(); mu_config_uninit(&config); - return rv == MU_OK ? 0 : 1; + return rv ? 0 : 1; }