* many changes to the config system

This commit is contained in:
Dirk-Jan C. Binnema
2011-01-04 23:19:03 +02:00
parent 38f9772270
commit fade4172fe
32 changed files with 485 additions and 602 deletions

10
TODO
View File

@ -1,21 +1,21 @@
* Future release * Future release
** release 0.10 [9%] ** release 0.10 [0%]
- [ ] mu stats - [ ] mu stats
- [ ] ansi-colors in output - [ ] ansi-colors in output
- [ ] config system (config file) (?) - [ ] config system (config file) (?)
- [ ] detect mail threads (?) - [ ] detect mail threads (?)
- [ ] xml,json,sexp output
- [ ] completion for zsh - [ ] completion for zsh
- [ ] don't make test mail files executable - [ ] don't make test mail files executable
** release 0.9.2 ** release 0.9.2 [20%]
- [ ] xml,json,sexp output
- [ ] separate exit code for 'not found' vs other errors - [ ] separate exit code for 'not found' vs other errors
- [ ] fix build for Solaris - [ ] fix build for Solaris
- [ ] clearer errors when /home/user does not exist - [X] clearer errors when /home/user does not exist
- [ ] fix -pedantic build - [X] fix -pedantic build
- [ ] make commit batch size configure param - [ ] make commit batch size configure param
- [ ] better 'usage' info - [ ] better 'usage' info
- [ ] add version info to output of configure, mu.log - [ ] add version info to output of configure, mu.log

View File

@ -53,11 +53,9 @@ libmu_la_SOURCES= \
mu-cmd-index.c \ mu-cmd-index.c \
mu-cmd-mkdir.c \ mu-cmd-mkdir.c \
mu-cmd-view.c \ mu-cmd-view.c \
mu-cmd.c \
mu-cmd.h \ mu-cmd.h \
mu-config.c \ mu-config.c \
mu-config.h \ mu-config.h \
mu-error.h \
mu-index.c \ mu-index.c \
mu-index.h \ mu-index.h \
mu-log.c \ mu-log.c \
@ -86,13 +84,10 @@ libmu_la_SOURCES= \
mu-msg.h \ mu-msg.h \
mu-msg-file.c \ mu-msg-file.c \
mu-msg-file.h \ mu-msg-file.h \
mu-output-link.c \ mu-output.c \
mu-output-link.h \ mu-output.h \
mu-output-plain.c \
mu-output-plain.h \
mu-query.cc \ mu-query.cc \
mu-query.h \ mu-query.h \
mu-result.h \
mu-runtime.c \ mu-runtime.c \
mu-runtime.h \ mu-runtime.h \
mu-store.cc \ mu-store.cc \

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify it ** 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 ** under the terms of the GNU General Public License as published by the
@ -29,7 +29,7 @@
#include "mu-util.h" #include "mu-util.h"
static gboolean static gboolean
save_numbered_parts (MuMsg *msg, MuConfigOptions *opts) save_numbered_parts (MuMsg *msg, MuConfig *opts)
{ {
gboolean rv; gboolean rv;
char **parts, **cur; char **parts, **cur;
@ -131,7 +131,7 @@ save_certain_parts (MuMsg *msg, gboolean attachments_only,
static gboolean static gboolean
save_parts (const char *path, MuConfigOptions *opts) save_parts (const char *path, MuConfig *opts)
{ {
MuMsg* msg; MuMsg* msg;
gboolean rv; gboolean rv;
@ -179,7 +179,7 @@ each_part_show (MuMsgPart *part, gpointer user_data)
static gboolean static gboolean
show_parts (const char* path, MuConfigOptions *opts) show_parts (const char* path, MuConfig *opts)
{ {
MuMsg* msg; MuMsg* msg;
GError *err; GError *err;
@ -202,7 +202,7 @@ show_parts (const char* path, MuConfigOptions *opts)
} }
static gboolean static gboolean
check_params (MuConfigOptions *opts) check_params (MuConfig *opts)
{ {
if (!opts->params[1]) { if (!opts->params[1]) {
g_warning ("usage: mu extract [options] <file>"); g_warning ("usage: mu extract [options] <file>");
@ -230,16 +230,17 @@ check_params (MuConfigOptions *opts)
return TRUE; return TRUE;
} }
gboolean MuExitCode
mu_cmd_extract (MuConfigOptions *opts) mu_cmd_extract (MuConfig *opts)
{ {
gboolean rv; int rv;
g_return_val_if_fail (opts, FALSE); g_return_val_if_fail (opts, MU_EXITCODE_ERROR);
g_return_val_if_fail (mu_cmd_equals (opts, "extract"), FALSE); g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_EXTRACT,
MU_EXITCODE_ERROR);
if (!check_params (opts)) if (!check_params (opts))
return FALSE; return MU_EXITCODE_ERROR;
if (!opts->parts && if (!opts->parts &&
!opts->save_attachments && !opts->save_attachments &&
@ -248,5 +249,5 @@ mu_cmd_extract (MuConfigOptions *opts)
else else
rv = save_parts (opts->params[1], opts); /* save */ rv = save_parts (opts->params[1], opts); /* save */
return rv; return rv ? MU_EXITCODE_OK : MU_EXITCODE_ERROR;
} }

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify it ** 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 ** under the terms of the GNU General Public License as published by the
@ -17,7 +17,7 @@
** **
*/ */
#ifdef HAVE_CONFIG_H #if HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /*HAVE_CONFIG_H*/ #endif /*HAVE_CONFIG_H*/
@ -39,9 +39,7 @@
#include "mu-util.h" #include "mu-util.h"
#include "mu-util-db.h" #include "mu-util-db.h"
#include "mu-cmd.h" #include "mu-cmd.h"
#include "mu-output-plain.h" #include "mu-output.h"
#include "mu-output-link.h"
static void static void
update_warning (void) update_warning (void)
@ -52,14 +50,11 @@ update_warning (void)
} }
static gboolean static gboolean
print_xapian_query (MuQuery *xapian, const gchar *query) print_xapian_query (MuQuery *xapian, const gchar *query)
{ {
char *querystr; char *querystr;
GError *err; GError *err;
MU_WRITE_LOG ("query: '%s' (xquery)", query);
err = NULL; err = NULL;
querystr = mu_query_as_string (xapian, query, &err); querystr = mu_query_as_string (xapian, query, &err);
@ -95,55 +90,15 @@ sort_field_from_string (const char* fieldstr)
} }
static size_t
print_rows (MuMsgIter *iter, const char *fields, size_t summary_len)
{
size_t count = 0;
if (mu_msg_iter_is_done (iter))
return 0;
do {
if (mu_output_plain_row (iter, fields, summary_len))
++count;
} while (mu_msg_iter_next (iter));
return count;
}
static size_t
make_links (MuMsgIter *iter, const char* linksdir, gboolean clearlinks)
{
size_t count = 0;
if (!mu_output_link_create_dir (linksdir, clearlinks))
return 0;
if (mu_msg_iter_is_done (iter))
return 0;
/* iterate over the found iters */
do {
/* ignore errors...*/
if (mu_output_link_row (iter, linksdir))
++count;
} while (mu_msg_iter_next (iter));
return count;
}
static gboolean static gboolean
run_query (MuQuery *xapian, const gchar *query, MuConfigOptions *opts) run_query (MuQuery *xapian, const gchar *query, MuConfig *opts,
size_t *count)
{ {
GError *err; GError *err;
MuMsgIter *iter; MuMsgIter *iter;
MuMsgFieldId sortid; MuMsgFieldId sortid;
size_t matches; gboolean rv;
sortid = MU_MSG_FIELD_ID_NONE; sortid = MU_MSG_FIELD_ID_NONE;
if (opts->sortfield) { if (opts->sortfield) {
@ -162,23 +117,24 @@ run_query (MuQuery *xapian, const gchar *query, MuConfigOptions *opts)
} }
if (opts->linksdir) if (opts->linksdir)
matches = make_links (iter, opts->linksdir, rv = mu_output_links (iter, opts->linksdir, opts->clearlinks,
opts->clearlinks); count);
else else
matches = print_rows (iter, opts->fields, rv = mu_output_plain (iter, opts->fields, opts->summary_len,
opts->summary_len); count);
if (matches == 0) if (count && *count == 0)
g_warning ("no matches found"); g_warning ("no matches found");
mu_msg_iter_destroy (iter); mu_msg_iter_destroy (iter);
return matches > 0; return rv;
} }
static gboolean static gboolean
query_params_valid (MuConfigOptions *opts) query_params_valid (MuConfig *opts)
{ {
const gchar *xpath; const gchar *xpath;
@ -200,7 +156,7 @@ query_params_valid (MuConfigOptions *opts)
} }
static gchar* static gchar*
resolve_bookmark (MuConfigOptions *opts) resolve_bookmark (MuConfig *opts)
{ {
MuBookmarks *bm; MuBookmarks *bm;
char* val; char* val;
@ -226,7 +182,7 @@ resolve_bookmark (MuConfigOptions *opts)
static gchar* static gchar*
get_query (MuConfigOptions *opts) get_query (MuConfig *opts)
{ {
gchar *query, *bookmarkval; gchar *query, *bookmarkval;
@ -274,46 +230,52 @@ db_is_ready (const char *xpath)
} }
gboolean MuExitCode
mu_cmd_find (MuConfigOptions *opts) mu_cmd_find (MuConfig *opts)
{ {
GError *err; GError *err;
MuQuery *xapian; MuQuery *xapian;
gboolean rv; gboolean rv;
gchar *query; gchar *query;
const gchar *xpath; const gchar *xpath;
size_t count;
g_return_val_if_fail (opts, FALSE); g_return_val_if_fail (opts, FALSE);
g_return_val_if_fail (mu_cmd_equals (opts, "find"), FALSE); g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_FIND, FALSE);
if (!query_params_valid (opts)) if (!query_params_valid (opts))
return FALSE; return MU_EXITCODE_ERROR;
xpath = mu_runtime_xapian_dir (); xpath = mu_runtime_xapian_dir ();
if (!db_is_ready(xpath)) if (!db_is_ready(xpath))
return FALSE; return MU_EXITCODE_ERROR;
/* first param is 'query', search params are after that */ /* first param is 'query', search params are after that */
query = get_query (opts); query = get_query (opts);
if (!query) if (!query)
return FALSE; return MU_EXITCODE_ERROR;
err = NULL; err = NULL;
xapian = mu_query_new (xpath, &err); xapian = mu_query_new (xpath, &err);
if (!xapian) { if (!xapian) {
g_warning ("error: %s", err->message); g_warning ("error: %s", err->message);
g_error_free (err); g_error_free (err);
return FALSE; return MU_EXITCODE_ERROR;
} }
if (opts->xquery) if (opts->xquery)
rv = print_xapian_query (xapian, query); rv = print_xapian_query (xapian, query);
else else
rv = run_query (xapian, query, opts); rv = run_query (xapian, query, opts, &count);
mu_query_destroy (xapian); mu_query_destroy (xapian);
g_free (query); g_free (query);
return rv; if (!rv)
return MU_EXITCODE_ERROR;
else if (count == 0)
return MU_EXITCODE_NO_MATCHES;
else
return MU_EXITCODE_OK;
} }

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify it ** 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 ** under the terms of the GNU General Public License as published by the
@ -17,7 +17,7 @@
** **
*/ */
#ifdef HAVE_CONFIG_H #if HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /*HAVE_CONFIG_H*/ #endif /*HAVE_CONFIG_H*/
@ -78,7 +78,7 @@ install_sig_handler (void)
static gboolean static gboolean
check_index_or_cleanup_params (MuConfigOptions *opts) check_index_or_cleanup_params (MuConfig *opts)
{ {
/* param[0] == 'index' or 'cleanup', there should be no /* param[0] == 'index' or 'cleanup', there should be no
* param[1] */ * param[1] */
@ -157,7 +157,7 @@ index_msg_cb (MuIndexStats* stats, void *user_data)
static gboolean static gboolean
database_version_check_and_update (MuConfigOptions *opts) database_version_check_and_update (MuConfig *opts)
{ {
const gchar *xpath; const gchar *xpath;
@ -200,9 +200,8 @@ show_time (unsigned t, unsigned processed)
} }
static MuExitCode
static gboolean cmd_cleanup (MuIndex *midx, MuConfig *opts, MuIndexStats *stats,
cmd_cleanup (MuIndex *midx, MuConfigOptions *opts, MuIndexStats *stats,
gboolean show_progress) gboolean show_progress)
{ {
MuResult rv; MuResult rv;
@ -221,13 +220,14 @@ cmd_cleanup (MuIndex *midx, MuConfigOptions *opts, MuIndexStats *stats,
show_time ((unsigned)(time(NULL)-t),stats->_processed); show_time ((unsigned)(time(NULL)-t),stats->_processed);
} }
return (rv == MU_OK || rv == MU_STOP) ? TRUE: FALSE; return (rv == MU_OK || rv == MU_STOP) ?
MU_EXITCODE_OK: MU_EXITCODE_ERROR;
} }
static gboolean static MuExitCode
cmd_index (MuIndex *midx, MuConfigOptions *opts, MuIndexStats *stats, cmd_index (MuIndex *midx, MuConfig *opts, MuIndexStats *stats,
gboolean show_progress) gboolean show_progress)
{ {
MuResult rv; MuResult rv;
@ -257,16 +257,16 @@ cmd_index (MuIndex *midx, MuConfigOptions *opts, MuIndexStats *stats,
"cleaned-up: %u", "cleaned-up: %u",
stats->_processed, stats->_updated, stats->_processed, stats->_updated,
stats->_cleaned_up); stats->_cleaned_up);
return TRUE; return MU_EXITCODE_OK;
} }
return FALSE; return MU_EXITCODE_ERROR;
} }
static gboolean static MuExitCode
cmd_index_or_cleanup (MuConfigOptions *opts) cmd_index_or_cleanup (MuConfig *opts)
{ {
gboolean rv; gboolean rv;
MuIndex *midx; MuIndex *midx;
@ -274,21 +274,16 @@ cmd_index_or_cleanup (MuConfigOptions *opts)
gboolean show_progress; gboolean show_progress;
GError *err; GError *err;
g_return_val_if_fail (opts, FALSE);
g_return_val_if_fail (mu_cmd_equals (opts, "index") ||
mu_cmd_equals (opts, "cleanup"), FALSE);
if (!check_index_or_cleanup_params (opts) || if (!check_index_or_cleanup_params (opts) ||
!database_version_check_and_update(opts)) !database_version_check_and_update(opts))
return FALSE; return MU_EXITCODE_ERROR;
err = NULL; err = NULL;
if (!(midx = mu_index_new (mu_runtime_xapian_dir(), opts->xbatchsize, if (!(midx = mu_index_new (mu_runtime_xapian_dir(),
&err))) { opts->xbatchsize, &err))) {
g_warning ("index/cleanup failed: %s", g_warning ("index/cleanup failed: %s", err->message);
err->message);
g_error_free (err); g_error_free (err);
return FALSE; return MU_EXITCODE_ERROR;
} }
/* note, 'opts->quiet' already cause g_message output not to /* note, 'opts->quiet' already cause g_message output not to
@ -298,34 +293,38 @@ cmd_index_or_cleanup (MuConfigOptions *opts)
mu_index_stats_clear (&stats); mu_index_stats_clear (&stats);
install_sig_handler (); install_sig_handler ();
if (mu_cmd_equals (opts, "index")) switch (opts->cmd) {
rv = cmd_index (midx, opts, &stats, show_progress); case MU_CONFIG_CMD_INDEX:
else if (mu_cmd_equals (opts, "cleanup")) rv = cmd_index (midx, opts, &stats, show_progress); break;
rv = cmd_cleanup (midx, opts, &stats, show_progress); case MU_CONFIG_CMD_CLEANUP:
else rv = cmd_cleanup (midx, opts, &stats, show_progress); break;
default:
rv = MU_EXITCODE_ERROR;
g_assert_not_reached (); g_assert_not_reached ();
}
mu_index_destroy (midx); mu_index_destroy (midx);
return rv; return rv;
} }
gboolean MuExitCode
mu_cmd_index (MuConfigOptions *opts) mu_cmd_index (MuConfig *opts)
{ {
g_return_val_if_fail (opts && mu_cmd_equals (opts, "index"), g_return_val_if_fail (opts, FALSE);
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_INDEX,
FALSE); FALSE);
return cmd_index_or_cleanup (opts); return cmd_index_or_cleanup (opts);
} }
gboolean MuExitCode
mu_cmd_cleanup (MuConfigOptions *opts) mu_cmd_cleanup (MuConfig *opts)
{ {
g_return_val_if_fail (opts && mu_cmd_equals (opts, "cleanup"), g_return_val_if_fail (opts, MU_EXITCODE_ERROR);
FALSE); g_return_val_if_fail (opts->cmd != MU_CONFIG_CMD_CLEANUP,
MU_EXITCODE_ERROR);
return cmd_index_or_cleanup (opts); return cmd_index_or_cleanup (opts);
} }

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify it ** 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 ** under the terms of the GNU General Public License as published by the
@ -17,7 +17,9 @@
** **
*/ */
#if HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
@ -27,22 +29,21 @@
#include "mu-maildir.h" #include "mu-maildir.h"
#include "mu-cmd.h" #include "mu-cmd.h"
#include "mu-util.h" #include "mu-util.h"
gboolean MuExitCode
mu_cmd_mkdir (MuConfigOptions *opts) mu_cmd_mkdir (MuConfig *opts)
{ {
int i; int i;
g_return_val_if_fail (opts, FALSE); g_return_val_if_fail (opts, MU_EXITCODE_ERROR);
g_return_val_if_fail (mu_cmd_equals (opts, "mkdir"), FALSE); g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_MKDIR,
MU_EXITCODE_ERROR);
if (!opts->params[1]) { if (!opts->params[1]) {
g_warning ( g_printerr ("usage: mu mkdir [-u,--mode=<mode>] "
"usage: mu mkdir [-u,--mode=<mode>] " "<dir> [more dirs]");
"<dir> [more dirs]"); return MU_EXITCODE_ERROR;
return FALSE;
} }
i = 1; i = 1;
@ -52,12 +53,12 @@ mu_cmd_mkdir (MuConfigOptions *opts)
if (!mu_maildir_mkdir (opts->params[i], opts->dirmode, if (!mu_maildir_mkdir (opts->params[i], opts->dirmode,
FALSE, &err)) FALSE, &err))
if (err && err->message) { if (err && err->message) {
g_warning ("%s", err->message); g_printerr ("mu: %s", err->message);
g_error_free (err); g_error_free (err);
} }
return FALSE; return 1;
++i; ++i;
} }
return TRUE; return MU_EXITCODE_OK;
} }

View File

@ -23,6 +23,8 @@
#include <glib.h> #include <glib.h>
#include "mu-config.h" #include "mu-config.h"
#error "foo"
/** /**
* execute the 'mkdir' command * execute the 'mkdir' command
* *

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify it ** 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 ** under the terms of the GNU General Public License as published by the
@ -17,7 +17,9 @@
** **
*/ */
#if HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
@ -28,7 +30,6 @@
#include "mu-msg.h" #include "mu-msg.h"
#include "mu-str.h" #include "mu-str.h"
#include "mu-cmd.h" #include "mu-cmd.h"
#include "mu-util.h" #include "mu-util.h"
@ -63,21 +64,22 @@ view_msg (MuMsg *msg, const gchar *fields, size_t summary_len)
return TRUE; return TRUE;
} }
gboolean MuExitCode
mu_cmd_view (MuConfigOptions *opts) mu_cmd_view (MuConfig *opts)
{ {
gboolean rv; int rv, i;
int i;
g_return_val_if_fail (opts, MU_EXITCODE_ERROR);
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_VIEW,
MU_EXITCODE_ERROR);
g_return_val_if_fail (opts, FALSE);
/* note: params[0] will be 'view' */ /* note: params[0] will be 'view' */
if (!opts->params[0] || !opts->params[1]) { if (!opts->params[0] || !opts->params[1]) {
g_warning ("usage: mu view [options] <file> [<files>]"); g_warning ("usage: mu view [options] <file> [<files>]");
return FALSE; return MU_EXITCODE_ERROR;
} }
rv = TRUE; rv = MU_EXITCODE_OK;
for (i = 1; opts->params[i] && rv; ++i) { for (i = 1; opts->params[i] && rv; ++i) {
GError *err = NULL; GError *err = NULL;
@ -85,10 +87,12 @@ mu_cmd_view (MuConfigOptions *opts)
if (!msg) { if (!msg) {
g_warning ("error: %s", err->message); g_warning ("error: %s", err->message);
g_error_free (err); g_error_free (err);
return FALSE; return MU_EXITCODE_ERROR;
} }
rv = view_msg (msg, NULL, opts->summary_len); if (!view_msg (msg, NULL, opts->summary_len))
rv = MU_EXITCODE_ERROR;
mu_msg_destroy (msg); mu_msg_destroy (msg);
} }

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify it ** 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 ** under the terms of the GNU General Public License as published by the
@ -17,7 +17,9 @@
** **
*/ */
#if HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
@ -44,10 +46,11 @@ static void
show_usage (gboolean noerror) show_usage (gboolean noerror)
{ {
const char* usage= const char* usage=
"usage: mu [options] command [parameters]\n" "usage: mu command [options] [parameters]\n"
"where command is one of index, find, view, mkdir, cleanup " "where command is one of index, find, view, mkdir, cleanup "
"or extract\n\n" "or extract\n\n"
"see the mu or mu-easy manpages for more information\n"; "see the mu, mu-<command> or mu-easy manpages for "
"more information\n";
if (noerror) if (noerror)
g_print ("%s", usage); g_print ("%s", usage);
@ -59,9 +62,11 @@ static void
show_version (void) show_version (void)
{ {
g_print ("mu (mail indexer/searcher) " VERSION "\n" g_print ("mu (mail indexer/searcher) " VERSION "\n"
"Copyright (C) 2008-2010 Dirk-Jan C. Binnema (GPLv3+)\n"); "Copyright (C) 2008-2011 Dirk-Jan C. Binnema (GPLv3+)\n");
} }
gboolean gboolean
mu_cmd_execute (MuConfigOptions *opts) mu_cmd_execute (MuConfigOptions *opts)
{ {
@ -87,6 +92,7 @@ mu_cmd_execute (MuConfigOptions *opts)
case MU_CONFIG_CMD_VIEW: return mu_cmd_view (opts); case MU_CONFIG_CMD_VIEW: return mu_cmd_view (opts);
case MU_CONFIG_CMD_UNKNOWN: case MU_CONFIG_CMD_UNKNOWN:
g_printerr ("mu: unknown command '%s'\n\n", opts->cmdstr);
show_usage (FALSE); show_usage (FALSE);
return FALSE; return FALSE;
default: default:

View File

@ -22,50 +22,19 @@
#define __MU_CMD_H__ #define __MU_CMD_H__
#include <glib.h> #include <glib.h>
#include "mu-config.h" #include <mu-config.h>
G_BEGIN_DECLS G_BEGIN_DECLS
enum _MuCmd {
MU_CMD_INDEX,
MU_CMD_FIND,
MU_CMD_CLEANUP,
MU_CMD_MKDIR,
MU_CMD_VIEW,
MU_CMD_EXTRACT,
MU_CMD_UNKNOWN
};
typedef enum _MuCmd MuCmd;
/**
* check whether the MuConfigOptions are for command X
*
* @param config the config options
* @param cmd the command to check (ie., "mkdir" or "find")
*
* @return TRUE if the options are for cmd, FALSE otherwise
*/
gboolean mu_cmd_equals (MuConfigOptions *config, const gchar *cmd);
/**
* try to execute whatever is specified on the command line
*
* @param config a config structure with the command line params
*
* @return TRUE if it succeeded, FALSE otherwise
*/
gboolean mu_cmd_execute (MuConfigOptions *config);
/** /**
* execute the 'mkdir' command * execute the 'mkdir' command
* *
* @param opts configuration options * @param opts configuration options
* *
* @return TRUE if the command succeeded, FALSE otherwise * @return MU_EXITCODE_OK (0) if the command succeeded,
* MU_EXITCODE_ERROR otherwise
*/ */
gboolean mu_cmd_mkdir (MuConfigOptions *opts); MuExitCode mu_cmd_mkdir (MuConfig *opts);
/** /**
@ -73,9 +42,10 @@ gboolean mu_cmd_mkdir (MuConfigOptions *opts);
* *
* @param opts configuration options * @param opts configuration options
* *
* @return TRUE if the command succeeded, FALSE otherwise * @return MU_EXITCODE_OK (0) if the command succeeded,
* MU_EXITCODE_ERROR otherwise
*/ */
gboolean mu_cmd_view (MuConfigOptions *opts); MuExitCode mu_cmd_view (MuConfig *opts);
/** /**
@ -83,9 +53,10 @@ gboolean mu_cmd_view (MuConfigOptions *opts);
* *
* @param opts configuration options * @param opts configuration options
* *
* @return TRUE if the command succeede, FALSE otherwise * @return MU_EXITCODE_OK (0) if the command succeeded,
* MU_EXITCODE_ERROR otherwise
*/ */
gboolean mu_cmd_index (MuConfigOptions *opts); MuExitCode mu_cmd_index (MuConfig *opts);
/** /**
@ -93,19 +64,21 @@ gboolean mu_cmd_index (MuConfigOptions *opts);
* *
* @param opts configuration options * @param opts configuration options
* *
* @return TRUE if the command succeede, FALSE otherwise * @return MU_EXITCODE_OK (0) if the command succeeds,
* MU_EXITCODE_ERROR otherwise
*/ */
gboolean mu_cmd_cleanup (MuConfigOptions *opts); MuExitCode mu_cmd_cleanup (MuConfig *opts);
/** /**
* execute the 'find' command * execute the 'find' command
* *
* @param opts configuration options * @param opts configuration options
* *
* @return TRUE if the command succeede, FALSE otherwise * @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
*/ */
gboolean mu_cmd_find (MuConfigOptions *opts); MuExitCode mu_cmd_find (MuConfig *opts);
/** /**
@ -113,9 +86,11 @@ gboolean mu_cmd_find (MuConfigOptions *opts);
* *
* @param opts configuration options * @param opts configuration options
* *
* @return TRUE if the command succeede, FALSE otherwise * @return MU_EXITCODE_OK (0) if the command succeeds,
* MU_EXITCODE_ERROR otherwise
*/ */
gboolean mu_cmd_extract (MuConfigOptions *opts); MuExitCode mu_cmd_extract (MuConfig *opts);
G_END_DECLS G_END_DECLS

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify it ** 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 ** under the terms of the GNU General Public License as published by the
@ -26,9 +26,10 @@
#include "mu-util.h" #include "mu-util.h"
#include "mu-config.h" #include "mu-config.h"
#include "mu-cmd.h"
static void static void
set_group_mu_defaults (MuConfigOptions *opts) set_group_mu_defaults (MuConfig *opts)
{ {
gchar *exp; gchar *exp;
@ -43,7 +44,7 @@ set_group_mu_defaults (MuConfigOptions *opts)
} }
static GOptionGroup* static GOptionGroup*
config_options_group_mu (MuConfigOptions *opts) config_options_group_mu (MuConfig *opts)
{ {
GOptionGroup *og; GOptionGroup *og;
GOptionEntry entries[] = { GOptionEntry entries[] = {
@ -69,7 +70,7 @@ config_options_group_mu (MuConfigOptions *opts)
} }
static void static void
set_group_index_defaults (MuConfigOptions * opts) set_group_index_defaults (MuConfig * opts)
{ {
gchar *exp; gchar *exp;
@ -86,7 +87,7 @@ set_group_index_defaults (MuConfigOptions * opts)
} }
static GOptionGroup* static GOptionGroup*
config_options_group_index (MuConfigOptions * opts) config_options_group_index (MuConfig * opts)
{ {
GOptionGroup *og; GOptionGroup *og;
GOptionEntry entries[] = { GOptionEntry entries[] = {
@ -115,7 +116,7 @@ config_options_group_index (MuConfigOptions * opts)
} }
static void static void
set_group_find_defaults (MuConfigOptions *opts) set_group_find_defaults (MuConfig *opts)
{ {
/* note, when no fields are specified, we use /* note, when no fields are specified, we use
* date-from-subject, and sort descending by date. If fields * date-from-subject, and sort descending by date. If fields
@ -143,7 +144,7 @@ set_group_find_defaults (MuConfigOptions *opts)
} }
static GOptionGroup* static GOptionGroup*
config_options_group_find (MuConfigOptions *opts) config_options_group_find (MuConfig *opts)
{ {
GOptionGroup *og; GOptionGroup *og;
GOptionEntry entries[] = { GOptionEntry entries[] = {
@ -163,6 +164,8 @@ config_options_group_find (MuConfigOptions *opts)
"output as symbolic links to a target maildir", NULL}, "output as symbolic links to a target maildir", NULL},
{"clearlinks", 0, 0, G_OPTION_ARG_NONE, &opts->clearlinks, {"clearlinks", 0, 0, G_OPTION_ARG_NONE, &opts->clearlinks,
"clear old links before filling a linksdir", NULL}, "clear old links before filling a linksdir", NULL},
/* {"output", 'o', 0, G_OPTION_ARG_STRING, &opts->output, */
/* "output type ('plain'(*), 'links', 'xml', 'json', 'sexp')", NULL}, */
{NULL, 0, 0, 0, NULL, NULL, NULL} {NULL, 0, 0, 0, NULL, NULL, NULL}
}; };
@ -175,7 +178,7 @@ config_options_group_find (MuConfigOptions *opts)
} }
static GOptionGroup * static GOptionGroup *
config_options_group_mkdir (MuConfigOptions *opts) config_options_group_mkdir (MuConfig *opts)
{ {
GOptionGroup *og; GOptionGroup *og;
GOptionEntry entries[] = { GOptionEntry entries[] = {
@ -196,7 +199,7 @@ config_options_group_mkdir (MuConfigOptions *opts)
} }
static GOptionGroup* static GOptionGroup*
config_options_group_extract(MuConfigOptions *opts) config_options_group_extract(MuConfig *opts)
{ {
GOptionGroup *og; GOptionGroup *og;
GOptionEntry entries[] = { GOptionEntry entries[] = {
@ -225,54 +228,57 @@ config_options_group_extract(MuConfigOptions *opts)
} }
static MuConfigCmd gboolean
cmd_from_params (int *argcp, char ***argvp) parse_cmd_from_params (MuConfig *opts,
int *argcp, char ***argvp)
{ {
int i; int i;
const char *cmd; typedef struct {
typedef struct { const gchar* _name;
const gchar* _name; MuConfigCmd _cmd;
MuConfigCmd _cmd; } Cmd;
} Cmd;
Cmd cmd_map[] = {
Cmd cmd_map[] = { { "index", MU_CONFIG_CMD_INDEX },
{ "index", MU_CONFIG_CMD_INDEX }, { "find", MU_CONFIG_CMD_FIND },
{ "find", MU_CONFIG_CMD_FIND }, { "cleanup", MU_CONFIG_CMD_CLEANUP },
{ "cleanup", MU_CONFIG_CMD_CLEANUP }, { "mkdir", MU_CONFIG_CMD_MKDIR },
{ "mkdir", MU_CONFIG_CMD_MKDIR }, { "view", MU_CONFIG_CMD_VIEW },
{ "view", MU_CONFIG_CMD_VIEW }, { "extract", MU_CONFIG_CMD_EXTRACT }
{ "extract", MU_CONFIG_CMD_EXTRACT } };
};
opts->cmd = MU_CONFIG_CMD_NONE;
opts->cmdstr = NULL;
if (*argcp < 2) /* no command found at all */
return FALSE;
else if ((**argvp)[1] == '-')
/* if the first param starts with '-', there is no
* command, just some option (like --version, --help
* etc.)*/
return TRUE;
if (*argcp < 2) opts->cmd = MU_CONFIG_CMD_UNKNOWN;
return MU_CONFIG_CMD_UNKNOWN; opts->cmdstr = (*argvp)[1];
for (i = 0; i != G_N_ELEMENTS(cmd_map); ++i)
cmd = (*argvp)[1]; /* commmand or option */ if (strcmp (opts->cmdstr, cmd_map[i]._name) == 0)
opts->cmd = cmd_map[i]._cmd;
for (i = 0; i != G_N_ELEMENTS(cmd_map); ++i)
if (strcmp (cmd, cmd_map[i]._name) == 0)
return cmd_map[i]._cmd;
/* if the first param starts with '-', there is no command, just some option return TRUE;
* (like --version, --help etc.)*/
if (cmd[0] == '-')
return MU_CONFIG_CMD_NONE;
return MU_CONFIG_CMD_UNKNOWN;
} }
static gboolean static gboolean
parse_params (MuConfigOptions *opts, int *argcp, char ***argvp) parse_params (MuConfig *opts, int *argcp, char ***argvp)
{ {
GError *err; GError *err;
GOptionContext *context; GOptionContext *context;
gboolean rv; gboolean rv;
opts->cmd = cmd_from_params (argcp, argvp); if (!parse_cmd_from_params (opts, argcp, argvp))
if (opts->cmd == MU_CONFIG_CMD_UNKNOWN)
return FALSE; return FALSE;
context = g_option_context_new("- mu general option"); context = g_option_context_new("- mu general option");
g_option_context_set_main_group(context, config_options_group_mu(opts)); g_option_context_set_main_group(context, config_options_group_mu(opts));
@ -289,57 +295,115 @@ parse_params (MuConfigOptions *opts, int *argcp, char ***argvp)
case MU_CONFIG_CMD_EXTRACT: case MU_CONFIG_CMD_EXTRACT:
g_option_context_add_group(context, config_options_group_extract(opts)); g_option_context_add_group(context, config_options_group_extract(opts));
break; break;
case MU_CONFIG_CMD_UNKNOWN:
default: default:
break; break;
} }
err = NULL; err = NULL;
rv = g_option_context_parse(context, argcp, argvp, &err); rv = g_option_context_parse(context, argcp, argvp, &err);
g_option_context_free (context);
if (!rv) { if (!rv) {
/* use g_printerr here, as logging is not yet initialized */ g_printerr ("mu: error in options: %s\n", err->message);
if (opts->cmd != MU_CONFIG_CMD_NONE)
g_printerr ("error in options for command: %s\n", err->message);
else
g_printerr ("error in options: %s\n", err->message);
g_error_free(err); g_error_free(err);
return FALSE;
} }
g_option_context_free(context);
/* fill in the defaults if user did not specify */ /* fill in the defaults if user did not specify */
set_group_mu_defaults(opts); set_group_mu_defaults(opts);
set_group_index_defaults(opts); set_group_index_defaults(opts);
set_group_find_defaults(opts); set_group_find_defaults(opts);
/* set_group_mkdir_defaults (opts); */ /* set_group_mkdir_defaults (opts); */
return rv;
}
gboolean
mu_config_init (MuConfigOptions *opts, int *argcp, char ***argvp)
{
g_return_val_if_fail(opts, FALSE);
memset(opts, 0, sizeof(MuConfigOptions));
/* defaults are set in parse_params */
if (argcp && argvp)
if (!parse_params(opts, argcp, argvp))
return FALSE;
return TRUE; return TRUE;
} }
void MuConfig*
mu_config_uninit (MuConfigOptions *opts) mu_config_new (int *argcp, char ***argvp)
{ {
g_return_if_fail(opts); MuConfig *config;
config = g_new0 (MuConfig, 1);
/* defaults are set in parse_params */
if (argcp && argvp)
if (!parse_params(config, argcp, argvp)) {
mu_config_destroy (config);
return NULL;
}
return config;
}
void
mu_config_destroy (MuConfig *opts)
{
if (!opts)
return;
g_free(opts->muhome); g_free(opts->muhome);
g_free(opts->maildir); g_free(opts->maildir);
g_free(opts->linksdir); g_free(opts->linksdir);
g_free(opts->targetdir); g_free(opts->targetdir);
g_strfreev(opts->params); g_strfreev(opts->params);
g_free (opts);
}
static void
show_usage (gboolean noerror)
{
const char* usage=
"usage: mu command [options] [parameters]\n"
"where command is one of index, find, view, mkdir, cleanup "
"or extract\n\n"
"see the mu, mu-<command> or mu-easy manpages for "
"more information\n";
if (noerror)
g_print ("%s", usage);
else
g_printerr ("%s", usage);
}
static void
show_version (void)
{
g_print ("mu (mail indexer/searcher) " VERSION "\n"
"Copyright (C) 2008-2011 Dirk-Jan C. Binnema (GPLv3+)\n");
}
MuExitCode
mu_config_execute (MuConfig *opts)
{
g_return_val_if_fail (opts, MU_EXITCODE_ERROR);
if (opts->version) {
show_version ();
return MU_EXITCODE_OK;
}
if (!opts->params||!opts->params[0]) {/* no command? */
show_version ();
g_print ("\n");
show_usage (TRUE);
return MU_EXITCODE_ERROR;
}
switch (opts->cmd) {
case MU_CONFIG_CMD_CLEANUP: return mu_cmd_cleanup (opts);
case MU_CONFIG_CMD_EXTRACT: return mu_cmd_extract (opts);
case MU_CONFIG_CMD_FIND: return mu_cmd_find (opts);
case MU_CONFIG_CMD_INDEX: return mu_cmd_index (opts);
case MU_CONFIG_CMD_MKDIR: return mu_cmd_mkdir (opts);
case MU_CONFIG_CMD_VIEW: return mu_cmd_view (opts);
case MU_CONFIG_CMD_UNKNOWN:
g_printerr ("mu: unknown command '%s'\n\n", opts->cmdstr);
show_usage (FALSE);
return MU_EXITCODE_ERROR;
default:
g_return_val_if_reached (MU_EXITCODE_ERROR);
}
} }

View File

@ -22,93 +22,107 @@
#include <glib.h> #include <glib.h>
#include <sys/types.h> /* for mode_t */ #include <sys/types.h> /* for mode_t */
#include <mu-msg-fields.h>
#include "mu-msg-fields.h" #include <mu-util.h>
G_BEGIN_DECLS G_BEGIN_DECLS
enum _MuConfigCmd { enum _MuConfigCmd {
MU_CONFIG_CMD_INDEX, MU_CONFIG_CMD_INDEX,
MU_CONFIG_CMD_FIND, MU_CONFIG_CMD_FIND,
MU_CONFIG_CMD_CLEANUP, MU_CONFIG_CMD_CLEANUP,
MU_CONFIG_CMD_MKDIR, MU_CONFIG_CMD_MKDIR,
MU_CONFIG_CMD_VIEW, MU_CONFIG_CMD_VIEW,
MU_CONFIG_CMD_EXTRACT, MU_CONFIG_CMD_EXTRACT,
MU_CONFIG_CMD_NONE, MU_CONFIG_CMD_NONE,
MU_CONFIG_CMD_UNKNOWN MU_CONFIG_CMD_UNKNOWN
}; };
typedef enum _MuConfigCmd MuConfigCmd; typedef enum _MuConfigCmd MuConfigCmd;
/* struct with all configuration options for mu; it will be filled /* struct with all configuration options for mu; it will be filled
* from the config file, and/or command line arguments */ * from the config file, and/or command line arguments */
struct _MuConfigOptions { struct _MuConfig {
MuConfigCmd cmd; /* the command, or MU_CONFIG_CMD_NONE */ MuConfigCmd cmd; /* the command, or
const char *cmdstr; /* cmd string, for user info */ * MU_CONFIG_CMD_NONE */
const char *cmdstr; /* cmd string, for user info */
/* general options */ /* general options */
gboolean quiet; /* don't give any output */ gboolean quiet; /* don't give any output */
gboolean debug; /* spew out debug info */ gboolean debug; /* spew out debug info */
char *muhome; /* the House of Mu */ char *muhome; /* the House of Mu */
gboolean version; /* request mu version */ gboolean version; /* request mu version */
gboolean log_stderr; /* log to stderr (not logfile) */ gboolean log_stderr; /* log to stderr (not logfile) */
gchar** params; /* parameters (for querying) */ gchar** params; /* parameters (for querying) */
/* options for indexing */ /* options for indexing */
char *maildir; /* where the mails are */ char *maildir; /* where the mails are */
gboolean nocleanup; /* don't cleanup deleted mails from db */ gboolean nocleanup; /* don't cleanup deleted mails from db */
gboolean reindex; /* re-index existing mails */ gboolean reindex; /* re-index existing mails */
gboolean rebuild; /* empty the database before indexing */ gboolean rebuild; /* empty the database before indexing */
gboolean autoupgrade; /* automatically upgrade db gboolean autoupgrade; /* automatically upgrade db
* when needed */ * when needed */
int xbatchsize; /* batchsize for xapian commits, or 0 for default int xbatchsize; /* batchsize for xapian
* */ * commits, or 0 for
* default */
/* options for querying */ /* options for querying */
gboolean xquery; /* give the Xapian query instead of gboolean xquery; /* give the Xapian query
search results */ instead of search
char *fields; /* fields to show in output */ results */
char *sortfield; /* field to sort by (string) */ char *fields; /* fields to show in output */
gboolean descending; /* sort descending? */ char *sortfield; /* field to sort by (string) */
unsigned summary_len; /* max # of lines of msg in summary */ gboolean descending; /* sort descending? */
char *bookmark; /* use bookmark */ unsigned summary_len; /* max # of lines of msg in summary */
/* output to a maildir with symlinks */ char *bookmark; /* use bookmark */
char *linksdir; /* maildir to output symlinks */
gboolean clearlinks; /* clear a linksdir before filling */
mode_t dirmode; /* mode for the created maildir */
/* options for extracting parts */ /* output to a maildir with symlinks */
gboolean *save_all; /* extract all parts */ char *linksdir; /* maildir to output symlinks */
gboolean *save_attachments; /* extract all attachment parts */ gboolean clearlinks; /* clear a linksdir before filling */
gchar *parts; /* comma-sep'd list of parts to save */ mode_t dirmode; /* mode for the created maildir */
char *targetdir; /* where to save the attachments */
gboolean overwrite; /* should we overwrite same-named files */ /* options for extracting parts */
gboolean *save_all; /* extract all parts */
gboolean *save_attachments; /* extract all attachment parts */
gchar *parts; /* comma-sep'd list of parts
* to save */
char *targetdir; /* where to save the attachments */
gboolean overwrite; /* should we overwrite same-named files */
}; };
typedef struct _MuConfigOptions MuConfigOptions; typedef struct _MuConfig MuConfig;
/**
/** * create a new mu config object
*
* set default values for the configuration options; when you call * set default values for the configuration options; when you call
* mu_config_init, you should also call mu_config_uninit when the data * mu_config_init, you should also call mu_config_uninit when the data
* is no longer needed. * is no longer needed.
* *
* @param opts options * @param opts options
*/ */
gboolean mu_config_init (MuConfigOptions *opts, int *argcp, char ***argvp); MuConfig *mu_config_new (int *argcp, char ***argvp);
/**
/** * free the MuOptionsConfig structure; the the muhome and maildir
* free the MuOptionsCOnfig structure; the the muhome and maildir
* members are heap-allocated, so must be freed. * members are heap-allocated, so must be freed.
* *
* @param opts * @param opts a MuConfig struct, or NULL
*/ */
void mu_config_uninit (MuConfigOptions *opts); void mu_config_destroy (MuConfig *opts);
/**
* execute the command / options in this config
*
* @param opts the commands/options
*
* @return a value denoting the success/failure of the execution; MU_CONFIG_RETVAL_OK (0)
* for success, non-zero for a failure. This is to used for the exit
* code of the process
*/
MuExitCode mu_config_execute (MuConfig *opts);
G_END_DECLS G_END_DECLS

View File

@ -21,37 +21,9 @@
#ifndef __MU_ERROR_H__ #ifndef __MU_ERROR_H__
#define __MU_ERROR_H__ #define __MU_ERROR_H__
enum _MuError { G_BEGIN_DECLS
/* general xapian related error */
MU_ERROR_XAPIAN,
/* xapian dir is not accessible */
MU_ERROR_XAPIAN_DIR,
/* database version is not uptodate (ie. not compatible with
* the version that mu expects) */
MU_ERROR_XAPIAN_NOT_UPTODATE,
/* missing data for a document */
MU_ERROR_XAPIAN_MISSING_DATA,
/* (parsnng) error in the query */
MU_ERROR_QUERY,
/* gmime parsing related error */
MU_ERROR_GMIME,
/* File errors */
MU_ERROR_FILE_INVALID_SOURCE, G_END_DECLS
MU_ERROR_FILE_INVALID_NAME,
MU_ERROR_FILE_CANNOT_LINK,
MU_ERROR_FILE_CANNOT_OPEN,
MU_ERROR_FILE_CANNOT_READ,
MU_ERROR_FILE_CANNOT_CREATE,
MU_FILE_ERROR_CANNOT_MKDIR,
MU_FILE_ERROR_STAT_FAILED,
MU_FILE_ERROR_READDIR_FAILED,
/* generic file-related error */
MU_ERROR_FILE,
/* some other, internal error */
MU_ERROR_INTERNAL
};
typedef enum _MuError MuError;
#endif /*__MU_ERROR_H__*/ #endif /*__MU_ERROR_H__*/

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify ** 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 ** it under the terms of the GNU General Public License as published by
@ -22,8 +22,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <glib.h> #include <glib.h>
#include <mu-util.h> /* for MuResult */
#include "mu-result.h" /* for MuResult */ G_BEGIN_DECLS
/* opaque structure */ /* opaque structure */
struct _MuIndex; struct _MuIndex;
@ -178,4 +179,6 @@ MuResult mu_index_cleanup (MuIndex *index, MuIndexStats *stats,
*/ */
gboolean mu_index_stats_clear (MuIndexStats *stats); gboolean mu_index_stats_clear (MuIndexStats *stats);
G_END_DECLS
#endif /*__MU_INDEX_H__*/ #endif /*__MU_INDEX_H__*/

View File

@ -23,9 +23,7 @@
#include <glib.h> #include <glib.h>
#include <time.h> #include <time.h>
#include <sys/types.h> /* for mode_t */ #include <sys/types.h> /* for mode_t */
#include <mu-util.h> /* for MuResult, MuError */
#include <mu-result.h> /* for MuResult */
#include <mu-error.h>
G_BEGIN_DECLS G_BEGIN_DECLS

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify ** 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 ** it under the terms of the GNU General Public License as published by

View File

@ -91,7 +91,7 @@ mu_msg_file_get_flags_from_path (const char *path)
{ {
MuMsgFlags flags; MuMsgFlags flags;
MsgType mtype; MsgType mtype;
char *info = NULL; char *info = NULL, *cursor;
g_return_val_if_fail (path, MU_MSG_FLAG_NONE); g_return_val_if_fail (path, MU_MSG_FLAG_NONE);
g_return_val_if_fail (!g_str_has_suffix(path, G_DIR_SEPARATOR_S), g_return_val_if_fail (!g_str_has_suffix(path, G_DIR_SEPARATOR_S),
@ -99,42 +99,29 @@ mu_msg_file_get_flags_from_path (const char *path)
mtype = check_msg_type (path, &info); mtype = check_msg_type (path, &info);
if (mtype == MSG_TYPE_NEW) { /* we ignore any new-msg flags */ if (mtype == MSG_TYPE_NEW) { /* we ignore any new-msg flags */
g_free(info); flags = MU_MSG_FLAG_NEW;
return MU_MSG_FLAG_NEW; goto leave;
} }
flags = MU_MSG_FLAG_NONE; flags = MU_MSG_FLAG_NONE;
if (mtype == MSG_TYPE_CUR || mtype == MSG_TYPE_OTHER) { if ((mtype != MSG_TYPE_CUR && mtype != MSG_TYPE_OTHER) ||
char *cursor = info; !(info && info[0] == '2' && info[1] == ','))
/* only support the "2," format */ goto leave;
if (cursor && cursor[0] == '2' && cursor[1] == ',') {
cursor += 2; /* jump past 2, */ for (cursor = info + 2; *cursor; ++cursor) {
for (; *cursor; ++cursor) { switch (*cursor) {
switch (*cursor) { case 'P': flags |= MU_MSG_FLAG_PASSED; break;
case 'P': case 'T': flags |= MU_MSG_FLAG_TRASHED; break;
flags |= MU_MSG_FLAG_PASSED; case 'R': flags |= MU_MSG_FLAG_REPLIED; break;
break; case 'S': flags |= MU_MSG_FLAG_SEEN; break;
case 'T': case 'D': flags |= MU_MSG_FLAG_DRAFT; break;
flags |= MU_MSG_FLAG_TRASHED; case 'F': flags |= MU_MSG_FLAG_FLAGGED; break;
break; default: break; /* ignore */
case 'R':
flags |= MU_MSG_FLAG_REPLIED;
break;
case 'S':
flags |= MU_MSG_FLAG_SEEN;
break;
case 'D':
flags |= MU_MSG_FLAG_DRAFT;
break;
case 'F':
flags |= MU_MSG_FLAG_FLAGGED;
break;
}
}
} }
} }
g_free(info);
leave:
g_free(info);
return flags; return flags;
} }

View File

@ -25,6 +25,8 @@
#include "mu-msg.h" #include "mu-msg.h"
G_BEGIN_DECLS
/* we put the the MuMsg definition in this separate -priv file, so we /* we put the the MuMsg definition in this separate -priv file, so we
* can split the mu_msg implementations over separate files */ * can split the mu_msg implementations over separate files */
@ -57,4 +59,6 @@ struct _MuMsg {
MuMsgPrio _prio; MuMsgPrio _prio;
}; };
G_END_DECLS
#endif /*__MU_MSG_PRIV_H__*/ #endif /*__MU_MSG_PRIV_H__*/

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify ** 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 ** it under the terms of the GNU General Public License as published by
@ -20,6 +20,8 @@
#ifndef __MU_MSG_STATUS_H__ #ifndef __MU_MSG_STATUS_H__
#define __MU_MSG_STATUS_H__ #define __MU_MSG_STATUS_H__
G_BEGIN_DECLS
/* what kind of message is this; use by the indexer */ /* what kind of message is this; use by the indexer */
enum _MuMsgStatus { enum _MuMsgStatus {
MU_MSG_STATUS_NEW, /* message is new */ MU_MSG_STATUS_NEW, /* message is new */
@ -31,4 +33,6 @@ enum _MuMsgStatus {
}; };
typedef enum _MuMsgStatus MuMsgStatus; typedef enum _MuMsgStatus MuMsgStatus;
G_END_DECLS
#endif /*__MU_MSG_STATUS_H__*/ #endif /*__MU_MSG_STATUS_H__*/

View File

@ -20,11 +20,11 @@
#ifndef __MU_MSG_H__ #ifndef __MU_MSG_H__
#define __MU_MSG_H__ #define __MU_MSG_H__
#include "mu-msg-flags.h" #include <mu-msg-flags.h>
#include "mu-msg-fields.h" #include <mu-msg-fields.h>
#include "mu-msg-status.h" #include <mu-msg-status.h>
#include "mu-msg-prio.h" #include <mu-msg-prio.h>
#include "mu-error.h" #include <mu-util.h> /* for MuResult, MuError */
G_BEGIN_DECLS G_BEGIN_DECLS
@ -32,7 +32,6 @@ struct _MuMsg;
typedef struct _MuMsg MuMsg; typedef struct _MuMsg MuMsg;
/** /**
* initialize the GMime-system; this function needs to be called * initialize the GMime-system; this function needs to be called
* before doing anything else with MuMsg. mu_runtime_init will call * before doing anything else with MuMsg. mu_runtime_init will call

View File

@ -1,102 +0,0 @@
/*
** Copyright (C) 2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
** Free Software Foundation; either version 3, 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.
**
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "mu-msg.h"
#include "mu-maildir.h"
#include "mu-index.h"
#include "mu-msg-iter.h"
#include "mu-util.h"
#include "mu-output-link.h"
/* create a linksdir if it not exist yet; if it already existed,
* remove old links if opts->clearlinks was specified */
gboolean
mu_output_link_create_dir (const char *linksdir, gboolean clearlinks)
{
GError *err;
g_return_val_if_fail (linksdir, FALSE);
err = NULL;
if (access (linksdir, F_OK) != 0) {
if (!mu_maildir_mkdir (linksdir, 0700, TRUE, &err))
goto fail;
} else if (clearlinks)
if (!mu_maildir_clear_links (linksdir, &err))
goto fail;
return TRUE;
fail:
if (err) {
g_warning ("%s", err->message ? err->message : "unknown error");
g_error_free (err);
}
return FALSE;
}
gboolean
mu_output_link_row (MuMsgIter *iter, const char* linksdir)
{
const char *path;
GError *err;
g_return_val_if_fail (iter, FALSE);
g_return_val_if_fail (linksdir, FALSE);
g_return_val_if_fail (!mu_msg_iter_is_done (iter), FALSE);
path = mu_msg_iter_get_field (iter, MU_MSG_FIELD_ID_PATH);
if (!path)
return FALSE;
/* this might happen if the database is not up-to-date, not an error */
if (access (path, R_OK) != 0) {
if (errno == ENOENT)
g_warning ("cannot find source message %s: "
"the database is not up-to-date", path);
else
g_warning ("cannot read source message %s: %s", path,
strerror (errno));
return FALSE;
}
err = NULL;
if (!mu_maildir_link (path, linksdir, &err)) {
if (err) {
g_warning ("%s", err->message ? err->message : "unknown error");
g_error_free (err);
}
return FALSE;
}
return TRUE;
}

View File

@ -1,45 +0,0 @@
/*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
** Free Software Foundation; either version 3, 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.
**
*/
#ifndef __MU_OUTPUT_LINK_H__
#define __MU_OUTPUT_LINK_H__
/**
* create a target maildir to store the links if it does not exist yet
*
* @param linksdir path to the toplevel Maildir to create
* @param clearlinks if TRUE, clear any existing links in the target maildir
*
* @return TRUE if succeeded, FALSE otherwise
*/
gboolean mu_output_link_create_dir (const char *linksdir, gboolean clearlinks);
/**
* create a symlink for for a message. the target dir should already
* exist, use mu_output_link_create_dir if needed.
*
* @param iter iterator pointing to a message row
* @param fields the fields to print (see MuMsgFields)
* @param summary_len number of lines to include in message summary
*
* @return TRUE if the printing succeeded, FALSE in case of error
*/
gboolean mu_output_link_row (MuMsgIter *iter, const char *linksdir);
#endif /*__MU_OUTPUT_LINK_H__*/

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify it ** 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 ** under the terms of the GNU General Public License as published by the
@ -17,7 +17,7 @@
** **
*/ */
#ifdef HAVE_CONFIG_H #if HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /*HAVE_CONFIG_H*/ #endif /*HAVE_CONFIG_H*/
@ -32,10 +32,6 @@
#include "mu-msg-iter.h" #include "mu-msg-iter.h"
#include "mu-str.h" #include "mu-str.h"
/* #include "mu-util.h" */
/* #include "mu-util-db.h" */
/* #include "mu-cmd.h" */
#include "mu-output-plain.h" #include "mu-output-plain.h"

View File

@ -22,7 +22,7 @@
#include <glib.h> #include <glib.h>
#include <mu-msg-iter.h> #include <mu-msg-iter.h>
#include <mu-error.h> #include <mu-util.h> /* for MuResult, MuError */
G_BEGIN_DECLS G_BEGIN_DECLS

View File

@ -20,11 +20,9 @@
#ifndef __MU_RESULT_H__ #ifndef __MU_RESULT_H__
#define __MU_RESULT_H__ #define __MU_RESULT_H__
enum _MuResult { G_BEGIN_DECLS
MU_OK, /* all went ok */
MU_STOP, /* user wants to stop */
MU_ERROR /* some other error occured */ G_END_DECLS
};
typedef enum _MuResult MuResult;
#endif /*__MU_RESULT__*/ #endif /*__MU_RESULT__*/

View File

@ -39,7 +39,7 @@ struct _MuRuntimeData {
gchar *_muhome; gchar *_muhome;
gchar *_xapian_dir; gchar *_xapian_dir;
gchar *_bookmarks_file; gchar *_bookmarks_file;
MuConfigOptions *_config; MuConfig *_config;
}; };
typedef struct _MuRuntimeData MuRuntimeData; typedef struct _MuRuntimeData MuRuntimeData;
@ -98,7 +98,7 @@ mu_runtime_init (const char* muhome_arg)
static gboolean static gboolean
init_log (MuConfigOptions *opts) init_log (MuConfig *opts)
{ {
if (opts->log_stderr) if (opts->log_stderr)
return mu_log_init_with_fd (fileno(stderr), FALSE, return mu_log_init_with_fd (fileno(stderr), FALSE,
@ -117,9 +117,8 @@ mu_runtime_init_from_cmdline (int *pargc, char ***pargv)
return FALSE; return FALSE;
_data = g_new0 (MuRuntimeData, 1); _data = g_new0 (MuRuntimeData, 1);
_data->_config = g_new0 (MuConfigOptions, 1); _data->_config = mu_config_new (pargc, pargv);
if (!_data->_config) {
if (!mu_config_init (_data->_config, pargc, pargv)) {
runtime_free (); runtime_free ();
return FALSE; return FALSE;
} }
@ -148,10 +147,7 @@ runtime_free (void)
g_free (_data->_xapian_dir); g_free (_data->_xapian_dir);
g_free (_data->_muhome); g_free (_data->_muhome);
if (_data->_config) { mu_config_destroy (_data->_config);
mu_config_uninit (_data->_config);
g_free (_data->_config);
}
mu_log_uninit(); mu_log_uninit();
@ -208,8 +204,8 @@ mu_runtime_bookmarks_file (void)
} }
MuConfigOptions* MuConfig*
mu_runtime_config_options (void) mu_runtime_config (void)
{ {
g_return_val_if_fail (_initialized, NULL); g_return_val_if_fail (_initialized, NULL);

View File

@ -90,7 +90,7 @@ const char* mu_runtime_bookmarks_file (void);
* *
* @return the configuration options * @return the configuration options
*/ */
MuConfigOptions* mu_runtime_config_options (void); MuConfig* mu_runtime_config (void);
G_END_DECLS G_END_DECLS

View File

@ -22,10 +22,8 @@
#include <glib.h> #include <glib.h>
#include <inttypes.h> #include <inttypes.h>
#include <mu-result.h>
#include <mu-msg.h> #include <mu-msg.h>
#include <mu-error.h> #include <mu-util.h> /* for MuResult, MuError */
G_BEGIN_DECLS G_BEGIN_DECLS

View File

@ -225,9 +225,61 @@ unsigned char mu_util_get_dtype_with_lstat (const char *path);
G_STMT_START { \ G_STMT_START { \
g_log (G_LOG_DOMAIN, \ g_log (G_LOG_DOMAIN, \
G_LOG_LEVEL_INFO, \ G_LOG_LEVEL_INFO, \
__VA_ARGS__); \ __VA_ARGS__); \
} G_STMT_END } G_STMT_END
enum _MuResult {
MU_OK, /* all went ok */
MU_STOP, /* user wants to stop */
MU_ERROR /* some other error occured */
};
typedef enum _MuResult MuResult;
enum _MuExitCode {
MU_EXITCODE_OK = 0,
MU_EXITCODE_ERROR = 1,
MU_EXITCODE_NO_MATCHES = 2
};
typedef enum _MuExitCode MuExitCode;
enum _MuError {
/* general xapian related error */
MU_ERROR_XAPIAN,
/* xapian dir is not accessible */
MU_ERROR_XAPIAN_DIR,
/* database version is not uptodate (ie. not compatible with
* the version that mu expects) */
MU_ERROR_XAPIAN_NOT_UPTODATE,
/* missing data for a document */
MU_ERROR_XAPIAN_MISSING_DATA,
/* (parsnng) error in the query */
MU_ERROR_QUERY,
/* gmime parsing related error */
MU_ERROR_GMIME,
/* File errors */
MU_ERROR_FILE_INVALID_SOURCE,
MU_ERROR_FILE_INVALID_NAME,
MU_ERROR_FILE_CANNOT_LINK,
MU_ERROR_FILE_CANNOT_OPEN,
MU_ERROR_FILE_CANNOT_READ,
MU_ERROR_FILE_CANNOT_CREATE,
MU_FILE_ERROR_CANNOT_MKDIR,
MU_FILE_ERROR_STAT_FAILED,
MU_FILE_ERROR_READDIR_FAILED,
/* generic file-related error */
MU_ERROR_FILE,
/* some other, internal error */
MU_ERROR_INTERNAL
};
typedef enum _MuError MuError;
G_END_DECLS G_END_DECLS
#endif /*__MU_UTIL_H__*/ #endif /*__MU_UTIL_H__*/

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify it ** 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 ** under the terms of the GNU General Public License as published by the
@ -18,21 +18,20 @@
*/ */
#include <glib.h> #include <glib.h>
#include "mu-cmd.h" #include "mu-cmd.h"
#include "mu-runtime.h" #include "mu-runtime.h"
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
gboolean rv; int rv;
if (!mu_runtime_init_from_cmdline (&argc, &argv)) if (!mu_runtime_init_from_cmdline (&argc, &argv))
return 1; return 1;
rv = mu_config_execute (mu_runtime_config());
rv = mu_cmd_execute (mu_runtime_config_options());
mu_runtime_uninit (); mu_runtime_uninit ();
return rv ? 0 : 1; return rv;
} }

View File

@ -37,19 +37,19 @@ noinst_PROGRAMS= $(TEST_PROGS)
noinst_LTLIBRARIES=libtestmucommon.la noinst_LTLIBRARIES=libtestmucommon.la
TEST_PROGS += test-mu-util TEST_PROGS += test-mu-util
test_mu_util_SOURCES= test-mu-util.c test_mu_util_SOURCES= test-mu-util.c dummy.cc
test_mu_util_LDADD= libtestmucommon.la test_mu_util_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-str TEST_PROGS += test-mu-str
test_mu_str_SOURCES= test-mu-str.c test_mu_str_SOURCES= test-mu-str.c dummy.cc
test_mu_str_LDADD= libtestmucommon.la test_mu_str_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-maildir TEST_PROGS += test-mu-maildir
test_mu_maildir_SOURCES= test-mu-maildir.c test_mu_maildir_SOURCES= test-mu-maildir.c dummy.cc
test_mu_maildir_LDADD= libtestmucommon.la test_mu_maildir_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-msg-fields TEST_PROGS += test-mu-msg-fields
test_mu_msg_fields_SOURCES= test-mu-msg-fields.c test_mu_msg_fields_SOURCES= test-mu-msg-fields.c dummy.cc
test_mu_msg_fields_LDADD= libtestmucommon.la test_mu_msg_fields_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-query TEST_PROGS += test-mu-query
@ -61,11 +61,11 @@ test_mu_cmd_SOURCES= test-mu-cmd.c dummy.cc
test_mu_cmd_LDADD= libtestmucommon.la test_mu_cmd_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-msg TEST_PROGS += test-mu-msg
test_mu_msg_SOURCES= test-mu-msg.c test_mu_msg_SOURCES= test-mu-msg.c dummy.cc
test_mu_msg_LDADD= libtestmucommon.la test_mu_msg_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-runtime TEST_PROGS += test-mu-runtime
test_mu_runtime_SOURCES= test-mu-runtime.c test_mu_runtime_SOURCES= test-mu-runtime.c dummy.cc
test_mu_runtime_LDADD= libtestmucommon.la test_mu_runtime_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-store TEST_PROGS += test-mu-store
@ -73,10 +73,9 @@ test_mu_store_SOURCES= test-mu-store.c dummy.cc
test_mu_store_LDADD= libtestmucommon.la test_mu_store_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-msg-file TEST_PROGS += test-mu-msg-file
test_mu_msg_file_SOURCES= test-mu-msg-file.c test_mu_msg_file_SOURCES= test-mu-msg-file.c dummy.cc
test_mu_msg_file_LDADD= libtestmucommon.la test_mu_msg_file_LDADD= libtestmucommon.la
libtestmucommon_la_SOURCES= \ libtestmucommon_la_SOURCES= \
test-mu-common.c \ test-mu-common.c \
test-mu-common.h test-mu-common.h

View File

@ -204,6 +204,8 @@ test_mu_extract_01 (void)
G_DIR_SEPARATOR, G_DIR_SEPARATOR,
G_DIR_SEPARATOR); G_DIR_SEPARATOR);
/* g_print ("[%s]", cmdline) */
output = erroutput = NULL; output = erroutput = NULL;
g_assert (g_spawn_command_line_sync (cmdline, &output, &erroutput, NULL, NULL)); g_assert (g_spawn_command_line_sync (cmdline, &output, &erroutput, NULL, NULL));
g_assert_cmpstr (output, g_assert_cmpstr (output,