* add 'mu_runtime' for initialization, keeping global state during runtime. update many.

This commit is contained in:
Dirk-Jan C. Binnema 2010-11-14 13:55:04 +02:00
parent 10d2cdd5da
commit 141b7298e9
11 changed files with 317 additions and 165 deletions

View File

@ -24,9 +24,8 @@
#include <gtk/gtk.h>
#include <string.h> /* for memset */
#include "mu-config.h"
#include "mu-log.h"
#include "mu-util.h"
#include "mu-runtime.h"
#include "mug-msg-list-view.h"
#include "mug-query-bar.h"
@ -147,13 +146,8 @@ on_shortcut_clicked (GtkWidget *w, const gchar *query, MugData *mdata)
static GtkWidget*
mug_shortcuts_bar (MugData *data)
{
gchar* bmpath;
bmpath = mu_util_guess_bookmark_file (data->muhome);
data->shortcuts = mug_shortcuts_new (bmpath);
data->shortcuts = mug_shortcuts_new (mu_runtime_bookmarks_file());
g_free (bmpath);
g_signal_connect (G_OBJECT(data->shortcuts), "clicked",
G_CALLBACK(on_shortcut_clicked), data);
@ -224,19 +218,15 @@ mug_query_area (MugData *mugdata)
GtkWidget *paned;
GtkWidget *scrolled;
gchar* xdir;
queryarea = gtk_vbox_new (FALSE, 2);
paned = gtk_vpaned_new ();
paned = gtk_vpaned_new ();
xdir = mu_util_guess_xapian_dir (mugdata->muhome);
mugdata->mlist = mug_msg_list_view_new(xdir);
g_free (xdir);
mugdata->mlist = mug_msg_list_view_new(mu_runtime_xapian_dir());
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolled),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER(scrolled), mugdata->mlist);
gtk_paned_add1 (GTK_PANED (paned), scrolled);
@ -248,7 +238,7 @@ mug_query_area (MugData *mugdata)
gtk_paned_add2 (GTK_PANED (paned), mugdata->msgview);
mugdata->querybar = mug_querybar();
g_signal_connect (G_OBJECT(mugdata->querybar), "query_changed",
g_signal_connect (G_OBJECT(mugdata->querybar), "query-changed",
G_CALLBACK(on_query_changed),
mugdata);
@ -329,6 +319,8 @@ main (int argc, char *argv[])
g_printerr ("mug: error in options\n");
return 1;
}
mu_runtime_init (mugdata.muhome);
mugshell = mug_shell (&mugdata);
g_signal_connect(G_OBJECT(mugshell), "destroy",
@ -339,6 +331,8 @@ main (int argc, char *argv[])
gtk_main ();
g_free (mugdata.muhome);
mu_runtime_uninit ();
return 0;
}

View File

@ -89,6 +89,8 @@ libmu_la_SOURCES= \
mu-query.cc \
mu-query.h \
mu-result.h \
mu-runtime.c \
mu-runtime.h \
mu-store.cc \
mu-store.h \
mu-util-db.cc \

View File

@ -36,6 +36,8 @@
#include "mu-msg-str.h"
#include "mu-bookmarks.h"
#include "mu-runtime.h"
#include "mu-util.h"
#include "mu-util-db.h"
#include "mu-cmd.h"
@ -164,16 +166,20 @@ run_query (MuQuery *xapian, const gchar *query, MuConfigOptions *opts)
static gboolean
query_params_valid (MuConfigOptions *opts)
{
const gchar *xpath;
if (opts->linksdir)
if (opts->xquery) {
g_printerr ("Invalid option for '--linksdir'\n");
return FALSE;
}
if (mu_util_check_dir (opts->xpath, TRUE, FALSE))
return TRUE;
g_printerr ("%s is not a readable Xapian directory\n", opts->xpath);
xpath = mu_runtime_xapian_dir();
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;
@ -184,10 +190,12 @@ resolve_bookmark (MuConfigOptions *opts)
{
MuBookmarks *bm;
char* val;
const gchar *bmfile;
bm = mu_bookmarks_new (opts->bmpath);
bmfile = mu_runtime_bookmarks_file();
bm = mu_bookmarks_new (bmfile);
if (!bm) {
g_warning ("Failed to open bookmarks file '%s'", opts->bmpath);
g_warning ("Failed to open bookmarks file '%s'", bmfile);
return FALSE;
}
@ -237,6 +245,7 @@ mu_cmd_find (MuConfigOptions *opts)
MuQuery *xapian;
gboolean rv;
gchar *query;
const gchar *xpath;
g_return_val_if_fail (opts, FALSE);
g_return_val_if_fail (mu_cmd_equals (opts, "find"), FALSE);
@ -244,12 +253,14 @@ mu_cmd_find (MuConfigOptions *opts)
if (!query_params_valid (opts))
return FALSE;
if (mu_util_db_is_empty (opts->xpath)) {
xpath = mu_runtime_xapian_dir ();
if (mu_util_db_is_empty (xpath)) {
g_warning ("Database is empty; use 'mu index' to add messages");
return FALSE;
}
if (!mu_util_db_version_up_to_date (opts->xpath)) {
if (!mu_util_db_version_up_to_date (xpath)) {
update_warning ();
return FALSE;
}
@ -259,7 +270,7 @@ mu_cmd_find (MuConfigOptions *opts)
if (!query)
return FALSE;
xapian = mu_query_new (opts->xpath);
xapian = mu_query_new (xpath);
if (!xapian) {
g_warning ("Failed to create a Xapian query\n");
return FALSE;

View File

@ -34,6 +34,7 @@
#include "mu-msg.h"
#include "mu-index.h"
#include "mu-runtime.h"
static gboolean MU_CAUGHT_SIGNAL;
@ -147,24 +148,28 @@ index_msg_cb (MuIndexStats* stats, void *user_data)
static gboolean
database_version_check_and_update (MuConfigOptions *opts)
{
if (mu_util_db_is_empty (opts->xpath))
const gchar *xpath;
xpath = mu_runtime_xapian_dir ();
if (mu_util_db_is_empty (xpath))
return TRUE;
/* we empty the database before doing anything */
if (opts->rebuild) {
opts->reindex = TRUE;
g_message ("Clearing database %s", opts->xpath);
return mu_util_clear_database (opts->xpath);
g_message ("Clearing database %s", xpath);
return mu_util_clear_database (xpath);
}
if (mu_util_db_version_up_to_date (opts->xpath))
if (mu_util_db_version_up_to_date (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 first");
return mu_util_clear_database (opts->xpath);
return mu_util_clear_database (xpath);
}
update_warning ();
@ -191,7 +196,7 @@ cmd_cleanup (MuIndex *midx, MuConfigOptions *opts, MuIndexStats *stats,
MuResult rv;
time_t t;
g_message ("Cleaning up messages [%s]", opts->xpath);
g_message ("Cleaning up messages [%s]", mu_runtime_xapian_dir());
t = time (NULL);
rv = mu_index_cleanup (midx, stats,
@ -216,7 +221,8 @@ cmd_index (MuIndex *midx, MuConfigOptions *opts, MuIndexStats *stats,
MuResult rv;
time_t t;
g_message ("Indexing messages under %s [%s]", opts->maildir, opts->xpath);
g_message ("Indexing messages under %s [%s]", opts->maildir,
mu_runtime_xapian_dir());
t = time (NULL);
rv = mu_index_run (midx, opts->maildir, opts->reindex, stats,
@ -261,7 +267,7 @@ cmd_index_or_cleanup (MuConfigOptions *opts)
if (!check_index_params (opts) || !database_version_check_and_update(opts))
return FALSE;
if (!(midx = mu_index_new (opts->xpath))) {
if (!(midx = mu_index_new (mu_runtime_xapian_dir()))) {
g_warning ("Indexing/Cleanup failed");
return FALSE;
}

View File

@ -17,7 +17,7 @@
**
*/
#ifdef HAVE_CONFIG_H
#if HAVE_CONFIG_H
#include "config.h"
#endif /*HAVE_CONFIG_H*/
@ -30,11 +30,16 @@
static void
set_group_mu_defaults (MuConfigOptions *opts)
{
gchar *exp;
if (!opts->muhome)
opts->muhome = mu_util_guess_mu_homedir ();
/* note: xpath is is *not* settable from the cmdline */
opts->xpath = mu_util_guess_xapian_dir (opts->muhome);
exp = mu_util_dir_expand (opts->muhome);
if (exp) {
g_free (opts->muhome);
opts->muhome = exp;
}
}
@ -69,20 +74,16 @@ config_options_group_mu (MuConfigOptions *opts)
static void
set_group_index_defaults (MuConfigOptions *opts)
{
gchar *old;
old = opts->maildir;
if (opts->maildir)
opts->maildir = mu_util_dir_expand (opts->maildir);
else
gchar *exp;
if (!opts->maildir)
opts->maildir = mu_util_guess_maildir();
/* note, this may be an invalid dir, but we're checking for
* validity of the dir later */
if (!opts->maildir)
opts->maildir = old;
else
g_free (old);
exp = mu_util_dir_expand (opts->maildir);
if (exp) {
g_free (opts->maildir);
opts->maildir = exp;
}
}
@ -138,9 +139,6 @@ set_group_find_defaults (MuConfigOptions *opts)
/* FIXME: some warning when summary_len < 0? */
if (opts->summary_len < 1)
opts->summary_len = 0;
/* note: xpath is is *not* settable from the cmdline */
opts->bmpath = mu_util_guess_bookmark_file (opts->muhome);
}
@ -205,7 +203,8 @@ config_options_group_extract (MuConfigOptions *opts)
{
GOptionGroup *og;
GOptionEntry entries[] = {
{"save-attachments", 'a', 0, G_OPTION_ARG_NONE, &opts->save_attachments,
{"save-attachments", 'a', 0, G_OPTION_ARG_NONE,
&opts->save_attachments,
"save all attachments", NULL},
{"save-all", 0, 0, G_OPTION_ARG_NONE, &opts->save_all,
"save all parts (incl. non-attachments)", NULL},
@ -292,11 +291,9 @@ mu_config_uninit (MuConfigOptions *opts)
g_return_if_fail (opts);
g_free (opts->muhome);
g_free (opts->xpath);
g_free (opts->maildir);
g_free (opts->linksdir);
g_free (opts->targetdir);
g_free (opts->bmpath);
g_strfreev (opts->params);
}

View File

@ -36,7 +36,6 @@ struct _MuConfigOptions {
gboolean quiet; /* don't give any output */
gboolean debug; /* spew out debug info */
char *muhome; /* the House of Mu */
char *xpath; /* path to the Xapian dir (internal) */
gboolean version; /* request mu version */
gboolean log_stderr; /* log to stderr (not logfile) */
gchar** params; /* parameters (for querying) */
@ -56,7 +55,6 @@ struct _MuConfigOptions {
gboolean descending; /* sort descending? */
unsigned summary_len; /* max # of lines of msg in summary */
char *bookmark; /* use bookmark */
char *bmpath; /* path to bookmark file (internal) */
/* output to a maildir with symlinks */
char *linksdir; /* maildir to output symlinks */
gboolean clearlinks; /* clear a linksdir before filling */

207
src/mu-runtime.c Normal file
View File

@ -0,0 +1,207 @@
/*
** 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.
**
*/
#include "mu-runtime.h"
#include <glib-object.h>
#include <locale.h> /* for setlocale() */
#include <stdio.h> /* for fileno() */
#include "mu-config.h"
#include "mu-log.h"
#include "mu-util.h"
#define MU_XAPIAN_DIRNAME "xapian"
#define MU_BOOKMARKS_FILENAME "bookmarks"
struct _MuRuntimeData {
gchar *_muhome;
gchar *_xapian_dir;
gchar *_bookmarks_file;
MuConfigOptions *_config;
};
typedef struct _MuRuntimeData MuRuntimeData;
/* static, global data for this singleton */
static gboolean _initialized = FALSE;
static MuRuntimeData *_data = NULL;
static void runtime_free (void);
static gboolean
init_system (void)
{
/* without setlocale, non-ascii cmdline params (like search
* terms) won't work */
setlocale (LC_ALL, "");
/* on FreeBSD, it seems g_slice_new and friends lead to
* segfaults. So we shut if off */
#ifdef __FreeBSD__
if (!g_setenv ("G_SLICE", "always-malloc", TRUE)) {
g_critical ("cannot set G_SLICE");
return FALSE;
}
#endif /*__FreeBSD__*/
g_type_init ();
return TRUE;
}
gboolean
mu_runtime_init (const char* muhome_arg)
{
gchar *muhome;
g_return_val_if_fail (!_initialized, FALSE);
if (!init_system())
return FALSE;
if (muhome_arg)
muhome = g_strdup (muhome_arg);
else
muhome = mu_util_guess_mu_homedir ();
if (!mu_log_init (muhome, TRUE, FALSE, FALSE)) {
g_free (muhome);
return FALSE;
}
_data = g_new0 (MuRuntimeData, 1);
_data->_muhome = muhome;
return _initialized = TRUE;
}
static gboolean
init_log (MuConfigOptions *opts)
{
if (opts->log_stderr)
return mu_log_init_with_fd (fileno(stderr), FALSE,
opts->quiet, opts->debug);
else
return mu_log_init (opts->muhome, TRUE, opts->quiet,
opts->debug);
}
gboolean
mu_runtime_init_from_cmdline (int *pargc, char ***pargv)
{
g_return_val_if_fail (!_initialized, FALSE);
if (!init_system())
return FALSE;
_data = g_new0 (MuRuntimeData, 1);
_data->_config = g_new0 (MuConfigOptions, 1);
if (!mu_config_init (_data->_config, pargc, pargv)) {
runtime_free ();
return FALSE;
}
if (!init_log (_data->_config)) {
runtime_free ();
return FALSE;
}
_data->_muhome = g_strdup (_data->_config->muhome);
return _initialized = TRUE;
}
static void
runtime_free (void)
{
g_free (_data->_xapian_dir);
g_free (_data->_muhome);
if (_data->_config) {
mu_config_uninit (_data->_config);
g_free (_data->_config);
}
mu_log_uninit();
g_free (_data);
}
void
mu_runtime_uninit (void)
{
g_return_if_fail (_initialized);
runtime_free ();
_initialized = FALSE;
}
const char*
mu_runtime_mu_home_dir (void)
{
g_return_val_if_fail (_initialized, NULL);
return _data->_muhome;
}
const char*
mu_runtime_xapian_dir (void)
{
g_return_val_if_fail (_initialized, NULL);
if (!_data->_xapian_dir)
_data->_xapian_dir = g_strdup_printf ("%s%c%s", _data->_muhome,
G_DIR_SEPARATOR,
MU_XAPIAN_DIRNAME);
return _data->_xapian_dir;
}
const char*
mu_runtime_bookmarks_file (void)
{
g_return_val_if_fail (_initialized, NULL);
if (!_data->_bookmarks_file)
_data->_bookmarks_file =
g_strdup_printf ("%s%c%s",
_data->_muhome,
G_DIR_SEPARATOR,
MU_BOOKMARKS_FILENAME);
return _data->_bookmarks_file;
}
MuConfigOptions*
mu_runtime_config_options (void)
{
g_return_val_if_fail (_initialized, NULL);
return _data->_config;
}

38
src/mu-runtime.h Normal file
View File

@ -0,0 +1,38 @@
/*
** 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.
**
*/
#ifndef __MU_RUNTIME_H__
#define __MU_RUNTIME_H__
#include <glib.h>
#include "mu-config.h"
G_BEGIN_DECLS
gboolean mu_runtime_init (const char* muhome);
gboolean mu_runtime_init_from_cmdline (int *pargc, char ***pargv);
void mu_runtime_uninit (void);
const char* mu_runtime_mu_home_dir (void);
const char* mu_runtime_xapian_dir (void);
const char* mu_runtime_bookmarks_file (void);
MuConfigOptions* mu_runtime_config_options (void);
G_END_DECLS
#endif /*__MU_RUNTIME_H__*/

View File

@ -65,9 +65,7 @@ do_wordexp (const char *path)
return NULL;
}
/* if (wexp.we_wordc != 1) /\* not an *error*, we just take the first one *\/ */
/* g_debug ("%s: expansion ambiguous for '%s'", __FUNCTION__, path); */
/* we just pick the first one */
dir = g_strdup (wexp.we_wordv[0]);
/* strangely, below seems to lead to a crash on MacOS (BSD);
@ -194,33 +192,6 @@ mu_util_guess_mu_homedir (void)
".mu");
}
gchar*
mu_util_guess_xapian_dir (const char* muhome)
{
gchar *homedir, *xdir;
homedir = muhome ? g_strdup(muhome) : mu_util_guess_mu_homedir ();
xdir = g_strdup_printf ("%s%c%s", homedir, G_DIR_SEPARATOR,
MU_XAPIAN_DIR_NAME);
g_free (homedir);
return xdir;
}
gchar*
mu_util_guess_bookmark_file (const char* muhome)
{
gchar *homedir, *bmpath;
homedir = muhome ? g_strdup(muhome) : mu_util_guess_mu_homedir ();
bmpath = g_strdup_printf ("%s%c%s", homedir, G_DIR_SEPARATOR,
MU_BOOKMARK_FILENAME);
g_free (homedir);
return bmpath;
}
gboolean
mu_util_create_dir_maybe (const gchar *path)
{
@ -295,8 +266,7 @@ mu_util_create_writeable_fd (const char* filename, const char* dir,
g_debug ("%s: cannot open %s for writing: %s",
__FUNCTION__, fullpath, strerror(errno));
g_free (fullpath);
g_free (fullpath);
return fd;
}

View File

@ -61,38 +61,6 @@ char* mu_util_guess_maildir (void) G_GNUC_WARN_UNUSED_RESULT;
*/
gchar* mu_util_guess_mu_homedir (void);
/**
* guess the place of the xapian database (typically,
* ~/.mu/xapian/). Note, this directory does not necessarily
* exist. mu_util_check_dir can be use to check that
*
* @param muhome the mu home directory or NULL, in which the muhome
* directoy will be guessed as well
*
* @return the guessed xapian dir, which needs to be freed with g_free
* when no longer needed.
*/
gchar* mu_util_guess_xapian_dir (const gchar *muhome);
/**
* guess the place of the bookmark file (typically,
* ~/.mu/bookmarks). Note that this does not mean the file actually
* exists.
*
* @param muhome the mu home directory or NULL, in which the muhome
* directoy will be guessed as well
*
* @return the guessed mu bookmark file, which needs to be freed with
* g_free when no longer needed.
*/
gchar* mu_util_guess_bookmark_file (const gchar *muhome);
/**
* if path exists, check that's a read/writeable dir; otherwise try to
* create it (with perms 0700)

View File

@ -17,60 +17,21 @@
**
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <glib.h>
#include <stdio.h> /* for fileno() */
#include "mu-util.h"
#include "mu-config.h"
#include "mu-cmd.h"
#include "mu-log.h"
static gboolean
init_log (MuConfigOptions *opts)
{
gboolean rv;
if (opts->log_stderr)
rv = mu_log_init_with_fd (fileno(stderr), FALSE,
opts->quiet, opts->debug);
else
rv = mu_log_init (opts->muhome, TRUE, opts->quiet,
opts->debug);
/* we use g_printerr here because g_warning does not give
* the desired result when log initialization failed */
if (!rv)
g_printerr ("error: failed to initialize log\n");
return rv;
}
#include "mu-runtime.h"
int
main (int argc, char *argv[])
{
MuConfigOptions config;
gboolean rv;
if (!mu_util_init_system())
if (!mu_runtime_init_from_cmdline (&argc, &argv))
return 1;
if (!mu_config_init (&config, &argc, &argv))
return 1;
rv = mu_cmd_execute (mu_runtime_config_options());
if (!init_log (&config)) {
mu_config_uninit (&config);
return 1;
}
rv = mu_cmd_execute (&config);
mu_log_uninit();
mu_config_uninit (&config);
mu_runtime_uninit ();
return rv ? 0 : 1;
}