* use GError in various mu_maildir function to return error info

This commit is contained in:
Dirk-Jan C. Binnema 2010-12-05 16:29:53 +02:00
parent 8b70e6bace
commit 68af173246
6 changed files with 100 additions and 57 deletions

View File

@ -47,8 +47,14 @@ mu_cmd_mkdir (MuConfigOptions *opts)
i = 1; i = 1;
while (opts->params[i]) { while (opts->params[i]) {
GError *err;
err = NULL;
if (!mu_maildir_mkdir (opts->params[i], opts->dirmode, if (!mu_maildir_mkdir (opts->params[i], opts->dirmode,
FALSE)) FALSE, &err))
if (err && err->message) {
g_warning ("%s", err->message);
g_error_free (err);
}
return FALSE; return FALSE;
++i; ++i;
} }

View File

@ -33,10 +33,18 @@ enum _MuError {
MU_ERROR_XAPIAN_MISSING_DATA, MU_ERROR_XAPIAN_MISSING_DATA,
/* (parsnng) error in the query */ /* (parsnng) error in the query */
MU_ERROR_QUERY, MU_ERROR_QUERY,
/* file loading related error */
MU_ERROR_FILE,
/* gmime parsing related error */ /* gmime parsing related error */
MU_ERROR_GMIME, MU_ERROR_GMIME,
/* File errors */
MU_ERROR_FILE_INVALID_SOURCE,
MU_ERROR_FILE_CANNOT_LINK,
MU_ERROR_FILE_CANNOT_OPEN,
MU_ERROR_FILE_CANNOT_CREATE,
MU_FILE_ERROR_CANNOT_MKDIR,
/* generic file-related error */
MU_ERROR_FILE,
/* some other, internal error */ /* some other, internal error */
MU_ERROR_INTERNAL MU_ERROR_INTERNAL
}; };

View File

@ -36,7 +36,6 @@
#define MU_MAILDIR_WALK_MAX_FILE_SIZE (32*1000*1000) #define MU_MAILDIR_WALK_MAX_FILE_SIZE (32*1000*1000)
#define MU_MAILDIR_NOINDEX_FILE ".noindex" #define MU_MAILDIR_NOINDEX_FILE ".noindex"
#define MU_MAILDIR_CACHE_FILE ".mu.cache"
/* note: this function is *not* re-entrant, it returns a static buffer */ /* note: this function is *not* re-entrant, it returns a static buffer */
static const char* static const char*
@ -53,7 +52,7 @@ fullpath_s (const char* path, const char* name)
static gboolean static gboolean
create_maildir (const char *path, mode_t mode) create_maildir (const char *path, mode_t mode, GError **err)
{ {
int i; int i;
const gchar* subdirs[] = {"new", "cur", "tmp"}; const gchar* subdirs[] = {"new", "cur", "tmp"};
@ -75,8 +74,9 @@ create_maildir (const char *path, mode_t mode)
fullpath = fullpath_s (path, subdirs[i]); fullpath = fullpath_s (path, subdirs[i]);
rv = g_mkdir_with_parents (fullpath, (int)mode); rv = g_mkdir_with_parents (fullpath, (int)mode);
if (rv != 0) { if (rv != 0) {
g_warning ("g_mkdir_with_parents failed: %s", g_set_error (err, 0, MU_FILE_ERROR_CANNOT_MKDIR,
strerror (errno)); "g_mkdir_with_parents failed: %s",
strerror (errno));
return FALSE; return FALSE;
} }
} }
@ -85,7 +85,7 @@ create_maildir (const char *path, mode_t mode)
} }
static gboolean static gboolean
create_noindex (const char *path) create_noindex (const char *path, GError **err)
{ {
/* create a noindex file if requested */ /* create a noindex file if requested */
int fd; int fd;
@ -97,8 +97,9 @@ create_noindex (const char *path)
fd = creat (noindexpath, 0644); fd = creat (noindexpath, 0644);
if (fd < 0 || close (fd) != 0) { if (fd < 0 || close (fd) != 0) {
g_warning ("error in create_noindex: %s", g_set_error (err, 0, MU_ERROR_FILE_CANNOT_CREATE,
strerror (errno)); "error in create_noindex: %s",
strerror (errno));
return FALSE; return FALSE;
} }
@ -106,17 +107,17 @@ create_noindex (const char *path)
} }
gboolean gboolean
mu_maildir_mkdir (const char* path, mode_t mode, gboolean noindex) mu_maildir_mkdir (const char* path, mode_t mode, gboolean noindex, GError **err)
{ {
g_return_val_if_fail (path, FALSE); g_return_val_if_fail (path, FALSE);
MU_WRITE_LOG ("%s (%s, %o, %s)", __FUNCTION__, MU_WRITE_LOG ("%s (%s, %o, %s)", __FUNCTION__,
path, mode, noindex ?"TRUE":"FALSE"); path, mode, noindex ? "TRUE" : "FALSE");
if (!create_maildir (path, mode)) if (!create_maildir (path, mode, err))
return FALSE; return FALSE;
if (noindex && !create_noindex (path)) if (noindex && !create_noindex (path, err))
return FALSE; return FALSE;
return TRUE; return TRUE;
@ -125,7 +126,7 @@ mu_maildir_mkdir (const char* path, mode_t mode, gboolean noindex)
/* determine whether the source message is in 'new' or in 'cur'; /* determine whether the source message is in 'new' or in 'cur';
* we ignore messages in 'tmp' for obvious reasons */ * we ignore messages in 'tmp' for obvious reasons */
static gboolean static gboolean
check_subdir (const char *src, gboolean *in_cur) check_subdir (const char *src, gboolean *in_cur, GError **err)
{ {
gchar *srcpath; gchar *srcpath;
@ -136,7 +137,8 @@ check_subdir (const char *src, gboolean *in_cur)
else if (g_str_has_suffix (srcpath, "cur")) else if (g_str_has_suffix (srcpath, "cur"))
*in_cur = TRUE; *in_cur = TRUE;
else { else {
g_warning ("%s", "Invalid source message"); g_set_error(err, 0, MU_ERROR_FILE_INVALID_SOURCE,
"invalid source message '%s'", src);
return FALSE; return FALSE;
} }
g_free (srcpath); g_free (srcpath);
@ -145,12 +147,12 @@ check_subdir (const char *src, gboolean *in_cur)
} }
static gchar* static gchar*
get_target_fullpath (const char* src, const gchar *targetpath) get_target_fullpath (const char* src, const gchar *targetpath, GError **err)
{ {
gchar *targetfullpath, *srcfile, *srcpath, *c; gchar *targetfullpath, *srcfile, *srcpath, *c;
gboolean in_cur; gboolean in_cur;
if (!check_subdir (src, &in_cur)) if (!check_subdir (src, &in_cur, err))
return NULL; return NULL;
/* note: make the filename *cough* unique by making the pathname /* note: make the filename *cough* unique by making the pathname
@ -180,7 +182,7 @@ get_target_fullpath (const char* src, const gchar *targetpath)
gboolean gboolean
mu_maildir_link (const char* src, const char *targetpath) mu_maildir_link (const char* src, const char *targetpath, GError **err)
{ {
gchar *targetfullpath; gchar *targetfullpath;
int rv; int rv;
@ -188,16 +190,16 @@ mu_maildir_link (const char* src, const char *targetpath)
g_return_val_if_fail (src, FALSE); g_return_val_if_fail (src, FALSE);
g_return_val_if_fail (targetpath, FALSE); g_return_val_if_fail (targetpath, FALSE);
targetfullpath = get_target_fullpath (src, targetpath); targetfullpath = get_target_fullpath (src, targetpath, err);
if (!targetfullpath) if (!targetfullpath)
return FALSE; return FALSE;
rv = symlink (src, targetfullpath); rv = symlink (src, targetfullpath);
if (rv != 0) { if (rv != 0) {
g_warning ("error creating link %s => %s: %s", g_set_error (err, 0, MU_ERROR_FILE_CANNOT_LINK,
targetfullpath, src, "error creating link %s => %s: %s",
strerror (errno)); targetfullpath, src, strerror (errno));
g_free (targetfullpath); g_free (targetfullpath);
return FALSE; return FALSE;
} }
@ -574,7 +576,7 @@ mu_maildir_walk (const char *path, MuMaildirWalkMsgCallback cb_msg,
static gboolean static gboolean
clear_links (const gchar* dirname, DIR *dir) clear_links (const gchar* dirname, DIR *dir, GError **err)
{ {
struct dirent *entry; struct dirent *entry;
gboolean rv; gboolean rv;
@ -602,12 +604,13 @@ clear_links (const gchar* dirname, DIR *dir)
if (entry->d_type == DT_LNK) { if (entry->d_type == DT_LNK) {
if (unlink (fullpath) != 0) { if (unlink (fullpath) != 0) {
g_warning ("error unlinking %s: %s", /* don't use err */
fullpath, strerror(errno)); g_warning ("error unlinking %s: %s",
fullpath, strerror(errno));
rv = FALSE; rv = FALSE;
} }
} else /* DT_DIR, see check before*/ } else /* DT_DIR, see check before*/
rv = mu_maildir_clear_links (fullpath); rv = mu_maildir_clear_links (fullpath, err);
} }
return rv; return rv;
@ -615,7 +618,7 @@ clear_links (const gchar* dirname, DIR *dir)
gboolean gboolean
mu_maildir_clear_links (const gchar* path) mu_maildir_clear_links (const gchar* path, GError **err)
{ {
DIR *dir; DIR *dir;
gboolean rv; gboolean rv;
@ -624,14 +627,13 @@ mu_maildir_clear_links (const gchar* path)
dir = opendir (path); dir = opendir (path);
if (!dir) { if (!dir) {
g_warning ("failed to open %s: %s", path, g_set_error (err, 0, MU_ERROR_FILE_CANNOT_OPEN,
strerror(errno)); "failed to open %s: %s", path,
strerror(errno));
return FALSE; return FALSE;
} }
g_debug ("remove symlinks from %s", path); rv = clear_links (path, dir, err);
rv = clear_links (path, dir);
closedir (dir); closedir (dir);
return rv; return rv;

View File

@ -23,7 +23,9 @@
#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-result.h" /* for MuResult */
#include <mu-result.h> /* for MuResult */
#include <mu-error.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -37,10 +39,13 @@ G_BEGIN_DECLS
* @param mode the file mode (e.g., 0755) * @param mode the file mode (e.g., 0755)
* @param noindex add a .noindex file to the maildir, so it will be excluded * @param noindex add a .noindex file to the maildir, so it will be excluded
* from indexing by 'mu index' * from indexing by 'mu index'
* @param err if function returns FALSE, err may contain extra
* information. if err is NULL, does nothing
* *
* @return TRUE if creation succeeded, FALSE otherwise * @return TRUE if creation succeeded, FALSE otherwise
*/ */
gboolean mu_maildir_mkdir (const char* path, mode_t mode, gboolean noindex); gboolean mu_maildir_mkdir (const char* path, mode_t mode, gboolean noindex,
GError **err);
/** /**
@ -49,11 +54,13 @@ gboolean mu_maildir_mkdir (const char* path, mode_t mode, gboolean noindex);
* @param src the full path to the source message * @param src the full path to the source message
* @param targetpath the path to the target maildir; ie., *not* * @param targetpath the path to the target maildir; ie., *not*
* MyMaildir/cur, but just MyMaildir/. The function will figure out * MyMaildir/cur, but just MyMaildir/. The function will figure out
* the correct subdir then. * * the correct subdir then.
* @param err if function returns FALSE, err may contain extra
* information. if err is NULL, does nothing
* *
* @return * @return
*/ */
gboolean mu_maildir_link (const char* src, const char *targetpath); gboolean mu_maildir_link (const char* src, const char *targetpath, GError **err);
/** /**
* MuMaildirWalkMsgCallback -- callback function for * MuMaildirWalkMsgCallback -- callback function for
@ -105,10 +112,12 @@ MuResult mu_maildir_walk (const char *path, MuMaildirWalkMsgCallback cb_msg,
* recursively delete all the symbolic links in a directory tree * recursively delete all the symbolic links in a directory tree
* *
* @param dir top dir * @param dir top dir
* @param err if function returns FALSE, err may contain extra
* information. if err is NULL, does nothing
* *
* @return TRUE if it worked, FALSE in case of error * @return TRUE if it worked, FALSE in case of error
*/ */
gboolean mu_maildir_clear_links (const gchar* dir); gboolean mu_maildir_clear_links (const gchar* dir, GError **err);
G_END_DECLS G_END_DECLS

View File

@ -40,22 +40,34 @@
gboolean gboolean
mu_output_link_create_dir (const char *linksdir, gboolean clearlinks) mu_output_link_create_dir (const char *linksdir, gboolean clearlinks)
{ {
g_return_val_if_fail (linksdir, FALSE); GError *err;
g_return_val_if_fail (linksdir, FALSE);
if (access (linksdir, F_OK) != 0) { err = NULL;
if (!mu_maildir_mkmdir (linksdir, 0700, TRUE)) if (access (linksdir, F_OK) != 0) {
return FALSE; if (!mu_maildir_mkdir (linksdir, 0700, TRUE, &err))
goto fail;
} else if (clearlinks) } else if (clearlinks)
mu_maildir_clear_links (linksdir); if (!mu_maildir_clear_links (linksdir, &err))
goto fail;
return TRUE;
return TRUE;
fail:
if (err) {
g_warning ("%s", err->message ? err->message : "unknown error");
g_error_free (err);
}
return FALSE;
} }
gboolean gboolean
mu_output_link_row (MuMsgIter *iter, const char* linksdir) mu_output_link_row (MuMsgIter *iter, const char* linksdir)
{ {
const char *path; const char *path;
GError *err;
g_return_val_if_fail (iter, FALSE); g_return_val_if_fail (iter, FALSE);
g_return_val_if_fail (linksdir, FALSE); g_return_val_if_fail (linksdir, FALSE);
@ -63,21 +75,27 @@ mu_output_link_row (MuMsgIter *iter, const char* linksdir)
path = mu_msg_iter_get_field (iter, MU_MSG_FIELD_ID_PATH); path = mu_msg_iter_get_field (iter, MU_MSG_FIELD_ID_PATH);
if (!path) if (!path)
return FALSE; return FALSE;
/* this might happen if the database is not up-to-date, not an error */ /* this might happen if the database is not up-to-date, not an error */
if (access (path, R_OK) != 0) { if (access (path, R_OK) != 0) {
if (errno == ENOENT) if (errno == ENOENT)
g_warning ("cannot find source message %s: " g_warning ("cannot find source message %s: "
"the database is not up-to-date", path); "the database is not up-to-date", path);
else else
g_warning ("cannot read source message %s: %s", path, g_warning ("cannot read source message %s: %s", path,
strerror (errno)); strerror (errno));
return FALSE; return FALSE;
} }
if (!mu_maildir_link (path, linksdir)) err = NULL;
return FALSE; 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; return TRUE;
} }

View File

@ -42,7 +42,7 @@ test_mu_maildir_mkmdir_01 (void)
mdir = g_strdup_printf ("%s%c%s", tmpdir, G_DIR_SEPARATOR, mdir = g_strdup_printf ("%s%c%s", tmpdir, G_DIR_SEPARATOR,
"cuux"); "cuux");
g_assert_cmpuint (mu_maildir_mkdir (mdir, 0755, FALSE), g_assert_cmpuint (mu_maildir_mkdir (mdir, 0755, FALSE, NULL),
==, TRUE); ==, TRUE);
for (i = 0; i != G_N_ELEMENTS(subs); ++i) { for (i = 0; i != G_N_ELEMENTS(subs); ++i) {
@ -76,7 +76,7 @@ test_mu_maildir_mkmdir_02 (void)
mdir = g_strdup_printf ("%s%c%s", tmpdir, G_DIR_SEPARATOR, mdir = g_strdup_printf ("%s%c%s", tmpdir, G_DIR_SEPARATOR,
"cuux"); "cuux");
g_assert_cmpuint (mu_maildir_mkdir (mdir, 0755, TRUE), g_assert_cmpuint (mu_maildir_mkdir (mdir, 0755, TRUE, NULL),
==, TRUE); ==, TRUE);
for (i = 0; i != G_N_ELEMENTS(subs); ++i) { for (i = 0; i != G_N_ELEMENTS(subs); ++i) {
@ -113,7 +113,7 @@ test_mu_maildir_mkmdir_03 (void)
/* this must fail */ /* this must fail */
g_test_log_set_fatal_handler ((GTestLogFatalFunc)ignore_error, NULL); g_test_log_set_fatal_handler ((GTestLogFatalFunc)ignore_error, NULL);
g_assert_cmpuint (mu_maildir_mkdir (NULL, 0755, TRUE), g_assert_cmpuint (mu_maildir_mkdir (NULL, 0755, TRUE, NULL),
==, FALSE); ==, FALSE);
} }