From 68af1732462ed51b906e0dc1f37c37a7227e880c Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Sun, 5 Dec 2010 16:29:53 +0200 Subject: [PATCH] * use GError in various mu_maildir function to return error info --- src/mu-cmd-mkdir.c | 8 ++++- src/mu-error.h | 12 +++++-- src/mu-maildir.c | 62 +++++++++++++++++++------------------ src/mu-maildir.h | 19 +++++++++--- src/mu-output-link.c | 50 ++++++++++++++++++++---------- src/tests/test-mu-maildir.c | 6 ++-- 6 files changed, 100 insertions(+), 57 deletions(-) diff --git a/src/mu-cmd-mkdir.c b/src/mu-cmd-mkdir.c index 050fbc32..c7cec9de 100644 --- a/src/mu-cmd-mkdir.c +++ b/src/mu-cmd-mkdir.c @@ -47,8 +47,14 @@ mu_cmd_mkdir (MuConfigOptions *opts) i = 1; while (opts->params[i]) { + GError *err; + err = NULL; 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; ++i; } diff --git a/src/mu-error.h b/src/mu-error.h index 2cb1954a..3feaed5f 100644 --- a/src/mu-error.h +++ b/src/mu-error.h @@ -33,10 +33,18 @@ enum _MuError { MU_ERROR_XAPIAN_MISSING_DATA, /* (parsnng) error in the query */ MU_ERROR_QUERY, - /* file loading related error */ - MU_ERROR_FILE, /* gmime parsing related error */ 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 */ MU_ERROR_INTERNAL }; diff --git a/src/mu-maildir.c b/src/mu-maildir.c index 6fc78565..251f632d 100644 --- a/src/mu-maildir.c +++ b/src/mu-maildir.c @@ -36,7 +36,6 @@ #define MU_MAILDIR_WALK_MAX_FILE_SIZE (32*1000*1000) #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 */ static const char* @@ -53,7 +52,7 @@ fullpath_s (const char* path, const char* name) static gboolean -create_maildir (const char *path, mode_t mode) +create_maildir (const char *path, mode_t mode, GError **err) { int i; const gchar* subdirs[] = {"new", "cur", "tmp"}; @@ -75,8 +74,9 @@ create_maildir (const char *path, mode_t mode) fullpath = fullpath_s (path, subdirs[i]); rv = g_mkdir_with_parents (fullpath, (int)mode); if (rv != 0) { - g_warning ("g_mkdir_with_parents failed: %s", - strerror (errno)); + g_set_error (err, 0, MU_FILE_ERROR_CANNOT_MKDIR, + "g_mkdir_with_parents failed: %s", + strerror (errno)); return FALSE; } } @@ -85,7 +85,7 @@ create_maildir (const char *path, mode_t mode) } static gboolean -create_noindex (const char *path) +create_noindex (const char *path, GError **err) { /* create a noindex file if requested */ int fd; @@ -97,8 +97,9 @@ create_noindex (const char *path) fd = creat (noindexpath, 0644); if (fd < 0 || close (fd) != 0) { - g_warning ("error in create_noindex: %s", - strerror (errno)); + g_set_error (err, 0, MU_ERROR_FILE_CANNOT_CREATE, + "error in create_noindex: %s", + strerror (errno)); return FALSE; } @@ -106,17 +107,17 @@ create_noindex (const char *path) } 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); 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; - if (noindex && !create_noindex (path)) + if (noindex && !create_noindex (path, err)) return FALSE; 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'; * we ignore messages in 'tmp' for obvious reasons */ static gboolean -check_subdir (const char *src, gboolean *in_cur) +check_subdir (const char *src, gboolean *in_cur, GError **err) { gchar *srcpath; @@ -136,7 +137,8 @@ check_subdir (const char *src, gboolean *in_cur) else if (g_str_has_suffix (srcpath, "cur")) *in_cur = TRUE; else { - g_warning ("%s", "Invalid source message"); + g_set_error(err, 0, MU_ERROR_FILE_INVALID_SOURCE, + "invalid source message '%s'", src); return FALSE; } g_free (srcpath); @@ -145,12 +147,12 @@ check_subdir (const char *src, gboolean *in_cur) } 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; gboolean in_cur; - if (!check_subdir (src, &in_cur)) + if (!check_subdir (src, &in_cur, err)) return NULL; /* note: make the filename *cough* unique by making the pathname @@ -180,7 +182,7 @@ get_target_fullpath (const char* src, const gchar *targetpath) gboolean -mu_maildir_link (const char* src, const char *targetpath) +mu_maildir_link (const char* src, const char *targetpath, GError **err) { gchar *targetfullpath; 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 (targetpath, FALSE); - targetfullpath = get_target_fullpath (src, targetpath); + targetfullpath = get_target_fullpath (src, targetpath, err); if (!targetfullpath) return FALSE; rv = symlink (src, targetfullpath); if (rv != 0) { - g_warning ("error creating link %s => %s: %s", - targetfullpath, src, - strerror (errno)); + g_set_error (err, 0, MU_ERROR_FILE_CANNOT_LINK, + "error creating link %s => %s: %s", + targetfullpath, src, strerror (errno)); g_free (targetfullpath); return FALSE; } @@ -574,7 +576,7 @@ mu_maildir_walk (const char *path, MuMaildirWalkMsgCallback cb_msg, static gboolean -clear_links (const gchar* dirname, DIR *dir) +clear_links (const gchar* dirname, DIR *dir, GError **err) { struct dirent *entry; gboolean rv; @@ -602,12 +604,13 @@ clear_links (const gchar* dirname, DIR *dir) if (entry->d_type == DT_LNK) { if (unlink (fullpath) != 0) { - g_warning ("error unlinking %s: %s", - fullpath, strerror(errno)); + /* don't use err */ + g_warning ("error unlinking %s: %s", + fullpath, strerror(errno)); rv = FALSE; } } else /* DT_DIR, see check before*/ - rv = mu_maildir_clear_links (fullpath); + rv = mu_maildir_clear_links (fullpath, err); } return rv; @@ -615,7 +618,7 @@ clear_links (const gchar* dirname, DIR *dir) gboolean -mu_maildir_clear_links (const gchar* path) +mu_maildir_clear_links (const gchar* path, GError **err) { DIR *dir; gboolean rv; @@ -624,14 +627,13 @@ mu_maildir_clear_links (const gchar* path) dir = opendir (path); if (!dir) { - g_warning ("failed to open %s: %s", path, - strerror(errno)); + g_set_error (err, 0, MU_ERROR_FILE_CANNOT_OPEN, + "failed to open %s: %s", path, + strerror(errno)); return FALSE; } - g_debug ("remove symlinks from %s", path); - - rv = clear_links (path, dir); + rv = clear_links (path, dir, err); closedir (dir); return rv; diff --git a/src/mu-maildir.h b/src/mu-maildir.h index dd838762..52782a52 100644 --- a/src/mu-maildir.h +++ b/src/mu-maildir.h @@ -23,7 +23,9 @@ #include #include #include /* for mode_t */ -#include "mu-result.h" /* for MuResult */ + +#include /* for MuResult */ +#include G_BEGIN_DECLS @@ -37,10 +39,13 @@ G_BEGIN_DECLS * @param mode the file mode (e.g., 0755) * @param noindex add a .noindex file to the maildir, so it will be excluded * 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 */ -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 targetpath the path to the target maildir; ie., *not* * 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 */ -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 @@ -105,10 +112,12 @@ MuResult mu_maildir_walk (const char *path, MuMaildirWalkMsgCallback cb_msg, * recursively delete all the symbolic links in a directory tree * * @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 */ -gboolean mu_maildir_clear_links (const gchar* dir); +gboolean mu_maildir_clear_links (const gchar* dir, GError **err); G_END_DECLS diff --git a/src/mu-output-link.c b/src/mu-output-link.c index 104562d5..ccfc0fd9 100644 --- a/src/mu-output-link.c +++ b/src/mu-output-link.c @@ -40,22 +40,34 @@ gboolean 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) { - if (!mu_maildir_mkmdir (linksdir, 0700, TRUE)) - return FALSE; - - } else if (clearlinks) - mu_maildir_clear_links (linksdir); - - return TRUE; + 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); @@ -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); if (!path) - return FALSE; + 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); + 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; } - - if (!mu_maildir_link (path, linksdir)) - 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; } diff --git a/src/tests/test-mu-maildir.c b/src/tests/test-mu-maildir.c index 2475e964..b3bbf952 100644 --- a/src/tests/test-mu-maildir.c +++ b/src/tests/test-mu-maildir.c @@ -42,7 +42,7 @@ test_mu_maildir_mkmdir_01 (void) mdir = g_strdup_printf ("%s%c%s", tmpdir, G_DIR_SEPARATOR, "cuux"); - g_assert_cmpuint (mu_maildir_mkdir (mdir, 0755, FALSE), + g_assert_cmpuint (mu_maildir_mkdir (mdir, 0755, FALSE, NULL), ==, TRUE); 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, "cuux"); - g_assert_cmpuint (mu_maildir_mkdir (mdir, 0755, TRUE), + g_assert_cmpuint (mu_maildir_mkdir (mdir, 0755, TRUE, NULL), ==, TRUE); for (i = 0; i != G_N_ELEMENTS(subs); ++i) { @@ -113,7 +113,7 @@ test_mu_maildir_mkmdir_03 (void) /* this must fail */ 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); }