mirror of https://github.com/djcb/mu.git
* support '.noupdate' -- similar to '.noindex', maildirs containing
'.noupdate' will be ignored; however, they will _not_ be ignored when doing a full update (--rebuild)
This commit is contained in:
parent
5d5533c953
commit
9367f1ac6d
|
@ -309,7 +309,6 @@ mu_index_set_xbatch_size (MuIndex *index, guint xbatchsize)
|
|||
|
||||
|
||||
|
||||
|
||||
MuError
|
||||
mu_index_run (MuIndex *index, const char* path,
|
||||
gboolean reindex, MuIndexStats *stats,
|
||||
|
@ -337,6 +336,7 @@ mu_index_run (MuIndex *index, const char* path,
|
|||
rv = mu_maildir_walk (path,
|
||||
(MuMaildirWalkMsgCallback)on_run_maildir_msg,
|
||||
(MuMaildirWalkDirCallback)on_run_maildir_dir,
|
||||
reindex, /* re-index, ie. do a full update */
|
||||
&cb_data);
|
||||
|
||||
mu_store_flush (index->_store);
|
||||
|
@ -393,7 +393,7 @@ mu_index_stats (MuIndex *index, const char* path,
|
|||
|
||||
return mu_maildir_walk (path,
|
||||
(MuMaildirWalkMsgCallback)on_stats_maildir_file,
|
||||
NULL,&cb_data);
|
||||
NULL, FALSE, &cb_data);
|
||||
}
|
||||
|
||||
struct _CleanupData {
|
||||
|
|
199
lib/mu-maildir.c
199
lib/mu-maildir.c
|
@ -1,7 +1,7 @@
|
|||
/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/
|
||||
|
||||
/*
|
||||
** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
** Copyright (C) 2008-2012 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
|
||||
|
@ -47,6 +47,8 @@
|
|||
#include "mu-str.h"
|
||||
|
||||
#define MU_MAILDIR_NOINDEX_FILE ".noindex"
|
||||
#define MU_MAILDIR_NOUPDATE_FILE ".noupdate"
|
||||
|
||||
|
||||
/* On Linux (and some BSD), we have entry->d_type, but some file
|
||||
* systems (XFS, ReiserFS) do not support it, and set it DT_UNKNOWN.
|
||||
|
@ -88,13 +90,11 @@ create_maildir (const char *path, mode_t mode, GError **err)
|
|||
/* note, g_mkdir_with_parents won't detect an error if
|
||||
* there's already such a dir, but with the wrong
|
||||
* permissions; so we need to check */
|
||||
if (rv != 0 || !mu_util_check_dir(fullpath, TRUE, TRUE)) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE_CANNOT_MKDIR,
|
||||
"creating dir failed for %s: %s",
|
||||
fullpath,
|
||||
strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
if (rv != 0 || !mu_util_check_dir(fullpath, TRUE, TRUE))
|
||||
return mu_util_g_set_error
|
||||
(err,MU_ERROR_FILE_CANNOT_MKDIR,
|
||||
"creating dir failed for %s: %s",
|
||||
fullpath, strerror (errno));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -114,13 +114,10 @@ create_noindex (const char *path, GError **err)
|
|||
|
||||
/* note, if the 'close' failed, creation may still have
|
||||
* succeeded...*/
|
||||
if (fd < 0 || close (fd) != 0) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE_CANNOT_CREATE,
|
||||
"error in create_noindex: %s",
|
||||
strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (fd < 0 || close (fd) != 0)
|
||||
return mu_util_g_set_error (err, MU_ERROR_FILE_CANNOT_CREATE,
|
||||
"error in create_noindex: %s",
|
||||
strerror (errno));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -146,22 +143,22 @@ mu_maildir_mkdir (const char* path, mode_t mode, gboolean noindex, GError **err)
|
|||
static gboolean
|
||||
check_subdir (const char *src, gboolean *in_cur, GError **err)
|
||||
{
|
||||
gboolean rv;
|
||||
gchar *srcpath;
|
||||
|
||||
srcpath = g_path_get_dirname (src);
|
||||
|
||||
rv = TRUE;
|
||||
if (g_str_has_suffix (srcpath, "new"))
|
||||
*in_cur = FALSE;
|
||||
else if (g_str_has_suffix (srcpath, "cur"))
|
||||
*in_cur = TRUE;
|
||||
else {
|
||||
g_set_error(err, 0, MU_ERROR_FILE_INVALID_SOURCE,
|
||||
"invalid source message '%s'", src);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
rv = mu_util_g_set_error(err, MU_ERROR_FILE_INVALID_SOURCE,
|
||||
"invalid source message '%s'", src);
|
||||
g_free (srcpath);
|
||||
|
||||
return TRUE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
|
@ -207,23 +204,21 @@ mu_maildir_link (const char* src, const char *targetpath, GError **err)
|
|||
|
||||
rv = symlink (src, targetfullpath);
|
||||
|
||||
if (rv != 0) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE_CANNOT_LINK,
|
||||
"error creating link %s => %s: %s",
|
||||
targetfullpath, src, strerror (errno));
|
||||
g_free (targetfullpath);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (rv != 0)
|
||||
mu_util_g_set_error (err, MU_ERROR_FILE_CANNOT_LINK,
|
||||
"error creating link %s => %s: %s",
|
||||
targetfullpath, src, strerror (errno));
|
||||
g_free (targetfullpath);
|
||||
return TRUE;
|
||||
|
||||
return rv == 0 ? TRUE: FALSE;
|
||||
}
|
||||
|
||||
|
||||
static MuError
|
||||
process_dir (const char* path, const gchar *mdir,
|
||||
MuMaildirWalkMsgCallback msg_cb,
|
||||
MuMaildirWalkDirCallback dir_cb, void *data);
|
||||
MuMaildirWalkDirCallback dir_cb, gboolean full,
|
||||
void *data);
|
||||
|
||||
static MuError
|
||||
process_file (const char* fullpath, const gchar* mdir,
|
||||
|
@ -292,26 +287,26 @@ is_maildir_new_or_cur (const char *path)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* check if there is a noindex file (MU_MAILDIR_NOINDEX_FILE) in this
|
||||
|
||||
/* check if there path contains file; used for checking if there is
|
||||
* MU_MAILDIR_NOINDEX_FILE or MU_MAILDIR_NOUPDATE_FILE in this
|
||||
* dir; */
|
||||
static gboolean
|
||||
has_noindex_file (const char *path)
|
||||
dir_contains_file (const char *path, const char *file)
|
||||
{
|
||||
const char* noindexpath;
|
||||
const char* fullpath;
|
||||
|
||||
/* static buffer */
|
||||
noindexpath = mu_str_fullpath_s (path, MU_MAILDIR_NOINDEX_FILE);
|
||||
fullpath = mu_str_fullpath_s (path, file);
|
||||
|
||||
if (access (noindexpath, F_OK) == 0)
|
||||
if (access (fullpath, F_OK) == 0)
|
||||
return TRUE;
|
||||
else if (G_UNLIKELY(errno != ENOENT))
|
||||
g_warning ("error testing for noindex file %s: %s",
|
||||
noindexpath, strerror(errno));
|
||||
|
||||
g_warning ("error testing for %s/%s: %s",
|
||||
fullpath, file, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
is_dotdir_to_ignore (const char* dir)
|
||||
{
|
||||
|
@ -351,6 +346,9 @@ ignore_dir_entry (struct dirent *entry, unsigned char d_type)
|
|||
if (entry->d_name[0] == 'd' &&
|
||||
strncmp (entry->d_name, "dovecot", 7) == 0)
|
||||
return TRUE;
|
||||
/* ignore special files */
|
||||
if (entry->d_name[0] == '.')
|
||||
return TRUE;
|
||||
/* ignore core files */
|
||||
if (entry->d_name[0] == 'c' &&
|
||||
strncmp (entry->d_name, "core", 4) == 0)
|
||||
|
@ -390,7 +388,7 @@ static MuError
|
|||
process_dir_entry (const char* path, const char* mdir, struct dirent *entry,
|
||||
MuMaildirWalkMsgCallback cb_msg,
|
||||
MuMaildirWalkDirCallback cb_dir,
|
||||
void *data)
|
||||
gboolean full, void *data)
|
||||
{
|
||||
const char *fp;
|
||||
char* fullpath;
|
||||
|
@ -420,10 +418,9 @@ process_dir_entry (const char* path, const char* mdir, struct dirent *entry,
|
|||
MuError rv;
|
||||
/* my_mdir is the search maildir (the dir starting
|
||||
* with the top-level maildir as /, and without the
|
||||
* /tmp, /cur, /new
|
||||
*/
|
||||
* /tmp, /cur, /new */
|
||||
my_mdir = get_mdir_for_path (mdir, entry->d_name);
|
||||
rv = process_dir (fullpath, my_mdir, cb_msg, cb_dir, data);
|
||||
rv = process_dir (fullpath, my_mdir, cb_msg, cb_dir, full, data);
|
||||
g_free (my_mdir);
|
||||
|
||||
return rv;
|
||||
|
@ -470,7 +467,8 @@ dirent_cmp (struct dirent *d1, struct dirent *d2)
|
|||
static MuError
|
||||
process_dir_entries (DIR *dir, const char* path, const char* mdir,
|
||||
MuMaildirWalkMsgCallback msg_cb,
|
||||
MuMaildirWalkDirCallback dir_cb, void *data)
|
||||
MuMaildirWalkDirCallback dir_cb,
|
||||
gboolean full, void *data)
|
||||
{
|
||||
MuError result;
|
||||
GSList *lst, *c;
|
||||
|
@ -502,7 +500,7 @@ process_dir_entries (DIR *dir, const char* path, const char* mdir,
|
|||
|
||||
for (c = lst, result = MU_OK; c && result == MU_OK; c = g_slist_next(c))
|
||||
result = process_dir_entry (path, mdir, (struct dirent*)c->data,
|
||||
msg_cb, dir_cb, data);
|
||||
msg_cb, dir_cb, full, data);
|
||||
|
||||
g_slist_foreach (lst, (GFunc)dirent_destroy, NULL);
|
||||
g_slist_free (lst);
|
||||
|
@ -513,22 +511,22 @@ process_dir_entries (DIR *dir, const char* path, const char* mdir,
|
|||
|
||||
static MuError
|
||||
process_dir (const char* path, const char* mdir,
|
||||
MuMaildirWalkMsgCallback msg_cb,
|
||||
MuMaildirWalkDirCallback dir_cb, void *data)
|
||||
MuMaildirWalkMsgCallback msg_cb, MuMaildirWalkDirCallback dir_cb,
|
||||
gboolean full, void *data)
|
||||
{
|
||||
MuError result;
|
||||
DIR* dir;
|
||||
|
||||
/* if it has a noindex file, we ignore this dir */
|
||||
if (has_noindex_file (path)) {
|
||||
g_debug ("found .noindex: ignoring dir %s", path);
|
||||
if (dir_contains_file (path, MU_MAILDIR_NOINDEX_FILE) ||
|
||||
(!full && dir_contains_file (path, MU_MAILDIR_NOUPDATE_FILE))) {
|
||||
g_debug ("found noindex/noupdate: ignoring dir %s", path);
|
||||
return MU_OK;
|
||||
}
|
||||
|
||||
dir = opendir (path);
|
||||
if (G_UNLIKELY(!dir)) {
|
||||
g_warning ("%s: ignoring %s: %s", __FUNCTION__,
|
||||
path, strerror(errno));
|
||||
g_warning ("opendir failed %s: %s", path, strerror(errno));
|
||||
return MU_OK;
|
||||
}
|
||||
|
||||
|
@ -541,7 +539,7 @@ process_dir (const char* path, const char* mdir,
|
|||
}
|
||||
}
|
||||
|
||||
result = process_dir_entries (dir, path, mdir, msg_cb, dir_cb, data);
|
||||
result = process_dir_entries (dir, path, mdir, msg_cb, dir_cb, full, data);
|
||||
closedir (dir);
|
||||
|
||||
/* only run dir_cb if it exists and so far, things went ok */
|
||||
|
@ -554,7 +552,8 @@ process_dir (const char* path, const char* mdir,
|
|||
|
||||
MuError
|
||||
mu_maildir_walk (const char *path, MuMaildirWalkMsgCallback cb_msg,
|
||||
MuMaildirWalkDirCallback cb_dir, void *data)
|
||||
MuMaildirWalkDirCallback cb_dir, gboolean full,
|
||||
void *data)
|
||||
{
|
||||
MuError rv;
|
||||
char *mypath;
|
||||
|
@ -567,7 +566,7 @@ mu_maildir_walk (const char *path, MuMaildirWalkMsgCallback cb_msg,
|
|||
if (mypath[strlen(mypath)-1] == G_DIR_SEPARATOR)
|
||||
mypath[strlen(mypath)-1] = '\0';
|
||||
|
||||
rv = process_dir (mypath, NULL, cb_msg, cb_dir, data);
|
||||
rv = process_dir (mypath, NULL, cb_msg, cb_dir, full, data);
|
||||
g_free (mypath);
|
||||
|
||||
return rv;
|
||||
|
@ -617,8 +616,8 @@ clear_links (const gchar* dirname, DIR *dir, GError **err)
|
|||
}
|
||||
|
||||
if (errno != 0)
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE,
|
||||
"file error: %s", strerror(errno));
|
||||
mu_util_g_set_error (err, MU_ERROR_FILE,
|
||||
"file error: %s", strerror(errno));
|
||||
|
||||
return (rv == FALSE && errno == 0);
|
||||
}
|
||||
|
@ -633,12 +632,10 @@ mu_maildir_clear_links (const gchar* path, GError **err)
|
|||
g_return_val_if_fail (path, FALSE);
|
||||
|
||||
dir = opendir (path);
|
||||
if (!dir) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE_CANNOT_OPEN,
|
||||
"failed to open %s: %s", path,
|
||||
strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
if (!dir)
|
||||
return mu_util_g_set_error (err, MU_ERROR_FILE_CANNOT_OPEN,
|
||||
"failed to open %s: %s", path,
|
||||
strerror(errno));
|
||||
|
||||
rv = clear_links (path, dir, err);
|
||||
closedir (dir);
|
||||
|
@ -790,29 +787,23 @@ mu_maildir_get_new_path (const char *oldpath, const char *new_mdir,
|
|||
static gboolean
|
||||
msg_move_check_pre (const gchar *src, const gchar *dst, GError **err)
|
||||
{
|
||||
if (!g_path_is_absolute(src)) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE,
|
||||
"source is not an absolute path: '%s'", src);
|
||||
return FALSE;
|
||||
}
|
||||
if (!g_path_is_absolute(src))
|
||||
return mu_util_g_set_error
|
||||
(err, MU_ERROR_FILE,
|
||||
"source is not an absolute path: '%s'", src);
|
||||
|
||||
if (!g_path_is_absolute(dst)) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE,
|
||||
"target is not an absolute path: '%s'", dst);
|
||||
return FALSE;
|
||||
}
|
||||
if (!g_path_is_absolute(dst))
|
||||
return mu_util_g_set_error
|
||||
(err, MU_ERROR_FILE,
|
||||
"target is not an absolute path: '%s'", dst);
|
||||
|
||||
if (access (src, R_OK) != 0) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE, "cannot read %s",
|
||||
src);
|
||||
return FALSE;
|
||||
}
|
||||
if (access (src, R_OK) != 0)
|
||||
return mu_util_g_set_error (err, MU_ERROR_FILE,
|
||||
"cannot read %s", src);
|
||||
|
||||
if (access (dst, F_OK) == 0) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE, "%s already exists",
|
||||
dst);
|
||||
return FALSE;
|
||||
}
|
||||
if (access (dst, F_OK) == 0)
|
||||
return mu_util_g_set_error (err, MU_ERROR_FILE,
|
||||
"%s already exists", dst);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -821,17 +812,13 @@ static gboolean
|
|||
msg_move_check_post (const char *src, const char *dst, GError **err)
|
||||
{
|
||||
/* double check -- is the target really there? */
|
||||
if (access (dst, F_OK) != 0) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE, "can't find target (%s)",
|
||||
dst);
|
||||
return FALSE;
|
||||
}
|
||||
if (access (dst, F_OK) != 0)
|
||||
return mu_util_g_set_error
|
||||
(err, MU_ERROR_FILE, "can't find target (%s)", dst);
|
||||
|
||||
if (access (src, F_OK) == 0) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE, "source is still there (%s)",
|
||||
src);
|
||||
return FALSE;
|
||||
}
|
||||
if (access (src, F_OK) == 0)
|
||||
return mu_util_g_set_error
|
||||
(err, MU_ERROR_FILE, "source still there (%s)", src);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -843,16 +830,11 @@ msg_move (const char* src, const char *dst, GError **err)
|
|||
if (!msg_move_check_pre (src, dst, err))
|
||||
return FALSE;
|
||||
|
||||
if (rename (src, dst) != 0) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE, "error moving %s to %s",
|
||||
src, dst);
|
||||
return FALSE;
|
||||
}
|
||||
if (rename (src, dst) != 0)
|
||||
return mu_util_g_set_error
|
||||
(err, MU_ERROR_FILE,"error moving %s to %s", src, dst);
|
||||
|
||||
if (!msg_move_check_post (src, dst, err))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
return msg_move_check_post (src, dst, err);
|
||||
}
|
||||
|
||||
gchar*
|
||||
|
@ -869,18 +851,17 @@ mu_maildir_move_message (const char* oldpath, const char* targetmdir,
|
|||
newfullpath = mu_maildir_get_new_path (oldpath, targetmdir,
|
||||
newflags);
|
||||
if (!newfullpath) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE,
|
||||
"failed to determine target full path");
|
||||
return FALSE;
|
||||
mu_util_g_set_error (err, MU_ERROR_FILE,
|
||||
"failed to determine targetpath");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
src_is_target = (g_strcmp0 (oldpath, newfullpath) == 0);
|
||||
|
||||
if (!ignore_dups && src_is_target) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE_TARGET_EQUALS_SOURCE,
|
||||
"target equals source");
|
||||
return FALSE;
|
||||
mu_util_g_set_error (err, MU_ERROR_FILE_TARGET_EQUALS_SOURCE,
|
||||
"target equals source");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!src_is_target) {
|
||||
|
|
|
@ -96,7 +96,9 @@ typedef MuError (*MuMaildirWalkDirCallback)
|
|||
* dotdirs are visited (ie. '.dotdir/cur'), so this enables Maildir++.
|
||||
* (http://www.inter7.com/courierimap/README.maildirquota.html, search
|
||||
* for 'Mission statement'). In addition, dirs containing a file named
|
||||
* '.noindex' are ignored, as are their subdirectories.
|
||||
* '.noindex' are ignored, as are their subdirectories, and dirs
|
||||
* containing a file called '.noupdate' are ignored, unless @param
|
||||
* full is TRUE.
|
||||
*
|
||||
* mu_walk_maildir stops if the callbacks return something different
|
||||
* from MU_OK. For example, it can return MU_STOP to stop the scan, or
|
||||
|
@ -105,6 +107,7 @@ typedef MuError (*MuMaildirWalkDirCallback)
|
|||
* @param path the maildir path to scan
|
||||
* @param cb_msg the callback function called for each msg
|
||||
* @param cb_dir the callback function called for each dir
|
||||
* @param full whether do a full scan, i.e., to ignore .noupdate files
|
||||
* @param data user data pointer
|
||||
*
|
||||
* @return a scanner result; MU_OK if everything went ok,
|
||||
|
@ -112,7 +115,8 @@ typedef MuError (*MuMaildirWalkDirCallback)
|
|||
* case of error
|
||||
*/
|
||||
MuError mu_maildir_walk (const char *path, MuMaildirWalkMsgCallback cb_msg,
|
||||
MuMaildirWalkDirCallback cb_dir, void *data);
|
||||
MuMaildirWalkDirCallback cb_dir, gboolean full,
|
||||
void *data);
|
||||
/**
|
||||
* recursively delete all the symbolic links in a directory tree
|
||||
*
|
||||
|
|
|
@ -441,7 +441,7 @@ mu_util_fputs_encoded (const char *str, FILE *stream)
|
|||
|
||||
|
||||
|
||||
void
|
||||
gboolean
|
||||
mu_util_g_set_error (GError **err, MuError errcode, const char *frm, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
@ -459,6 +459,8 @@ mu_util_g_set_error (GError **err, MuError errcode, const char *frm, ...)
|
|||
g_set_error (err, MU_ERROR_DOMAIN, errcode, "%s", msg);
|
||||
|
||||
g_free (msg);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -439,13 +439,15 @@ typedef enum _MuError MuError;
|
|||
|
||||
|
||||
/**
|
||||
* set an error if it's not already set
|
||||
* set an error if it's not already set, and return FALSE
|
||||
*
|
||||
* @param err errptr, or NULL
|
||||
* @param errcode error code
|
||||
* @param frm printf-style format, followed by paremeters
|
||||
*
|
||||
* @return FALSE
|
||||
*/
|
||||
void mu_util_g_set_error (GError **err, MuError errcode, const char *frm, ...)
|
||||
gboolean mu_util_g_set_error (GError **err, MuError errcode, const char *frm, ...)
|
||||
G_GNUC_PRINTF(3,4);
|
||||
|
||||
|
||||
|
|
|
@ -256,6 +256,7 @@ test_mu_maildir_walk_01 (void)
|
|||
rv = mu_maildir_walk (tmpdir,
|
||||
(MuMaildirWalkMsgCallback)msg_cb,
|
||||
(MuMaildirWalkDirCallback)dir_cb,
|
||||
TRUE,
|
||||
&data);
|
||||
|
||||
g_assert_cmpuint (MU_OK, ==, rv);
|
||||
|
@ -269,7 +270,7 @@ test_mu_maildir_walk_01 (void)
|
|||
|
||||
|
||||
static void
|
||||
test_mu_maildir_walk_02 (void)
|
||||
test_mu_maildir_walk (void)
|
||||
{
|
||||
char *tmpdir, *cmd, *dir;
|
||||
WalkData data;
|
||||
|
@ -287,13 +288,13 @@ test_mu_maildir_walk_02 (void)
|
|||
|
||||
cmd = g_strdup_printf ("touch %s%c.noindex", dir, G_DIR_SEPARATOR);
|
||||
g_assert (g_spawn_command_line_sync (cmd, NULL, NULL, NULL, NULL));
|
||||
|
||||
g_free (cmd);
|
||||
g_free (dir);
|
||||
|
||||
rv = mu_maildir_walk (tmpdir,
|
||||
(MuMaildirWalkMsgCallback)msg_cb,
|
||||
(MuMaildirWalkDirCallback)dir_cb,
|
||||
TRUE,
|
||||
&data);
|
||||
|
||||
g_assert_cmpuint (MU_OK, ==, rv);
|
||||
|
@ -305,6 +306,90 @@ test_mu_maildir_walk_02 (void)
|
|||
g_free (tmpdir);
|
||||
}
|
||||
|
||||
static void
|
||||
test_mu_maildir_walk_with_noupdate (void)
|
||||
{
|
||||
char *tmpdir, *cmd, *dir;
|
||||
WalkData data;
|
||||
MuError rv;
|
||||
|
||||
tmpdir = copy_test_data ();
|
||||
|
||||
/* mark the 'new' dir with '.noindex', to ignore it */
|
||||
dir = g_strdup_printf ("%s%ctestdir%cnew", tmpdir,
|
||||
G_DIR_SEPARATOR, G_DIR_SEPARATOR);
|
||||
cmd = g_strdup_printf ("chmod 700 %s", dir);
|
||||
g_assert (g_spawn_command_line_sync (cmd, NULL, NULL, NULL, NULL));
|
||||
g_free (cmd);
|
||||
|
||||
memset (&data, 0, sizeof(WalkData));
|
||||
rv = mu_maildir_walk (tmpdir,
|
||||
(MuMaildirWalkMsgCallback)msg_cb,
|
||||
(MuMaildirWalkDirCallback)dir_cb,
|
||||
FALSE, /* ie., non-full update */
|
||||
&data);
|
||||
|
||||
g_assert_cmpuint (MU_OK, ==, rv);
|
||||
g_assert_cmpuint (data._file_count, ==, 17);
|
||||
g_assert_cmpuint (data._dir_entered,==, 5);
|
||||
g_assert_cmpuint (data._dir_left,==, 5);
|
||||
|
||||
|
||||
|
||||
/* again, full update. results should be the same, since there
|
||||
* is no noupdate yet */
|
||||
memset (&data, 0, sizeof(WalkData));
|
||||
rv = mu_maildir_walk (tmpdir,
|
||||
(MuMaildirWalkMsgCallback)msg_cb,
|
||||
(MuMaildirWalkDirCallback)dir_cb,
|
||||
TRUE, /* ie., full update */
|
||||
&data);
|
||||
|
||||
g_assert_cmpuint (MU_OK, ==, rv);
|
||||
g_assert_cmpuint (data._file_count, ==, 17);
|
||||
g_assert_cmpuint (data._dir_entered,==, 5);
|
||||
g_assert_cmpuint (data._dir_left,==, 5);
|
||||
|
||||
/* add a '.noupdate' file; this affects the outcome when the
|
||||
* 4th arg to mu_maildir_walk is FALSE */
|
||||
cmd = g_strdup_printf ("touch %s%c.noupdate", dir, G_DIR_SEPARATOR);
|
||||
g_assert (g_spawn_command_line_sync (cmd, NULL, NULL, NULL, NULL));
|
||||
g_free (cmd);
|
||||
|
||||
memset (&data, 0, sizeof(WalkData));
|
||||
rv = mu_maildir_walk (tmpdir,
|
||||
(MuMaildirWalkMsgCallback)msg_cb,
|
||||
(MuMaildirWalkDirCallback)dir_cb,
|
||||
FALSE, /* non-full update */
|
||||
&data);
|
||||
|
||||
g_assert_cmpuint (MU_OK, ==, rv);
|
||||
g_assert_cmpuint (data._file_count, ==, 13);
|
||||
|
||||
g_assert_cmpuint (data._dir_entered,==, 4);
|
||||
g_assert_cmpuint (data._dir_left,==, 4);
|
||||
|
||||
/* now run again, but do a full update */
|
||||
memset (&data, 0, sizeof(WalkData));
|
||||
rv = mu_maildir_walk (tmpdir,
|
||||
(MuMaildirWalkMsgCallback)msg_cb,
|
||||
(MuMaildirWalkDirCallback)dir_cb,
|
||||
TRUE, /* full update */
|
||||
&data);
|
||||
|
||||
g_assert_cmpuint (MU_OK, ==, rv);
|
||||
g_assert_cmpuint (data._file_count, ==, 17);
|
||||
|
||||
g_assert_cmpuint (data._dir_entered,==, 5);
|
||||
g_assert_cmpuint (data._dir_left,==, 5);
|
||||
|
||||
g_free (dir);
|
||||
g_free (tmpdir);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
|
@ -478,8 +563,10 @@ main (int argc, char *argv[])
|
|||
/* mu_util_maildir_walk */
|
||||
g_test_add_func ("/mu-maildir/mu-maildir-walk-01",
|
||||
test_mu_maildir_walk_01);
|
||||
g_test_add_func ("/mu-maildir/mu-maildir-walk-02",
|
||||
test_mu_maildir_walk_02);
|
||||
g_test_add_func ("/mu-maildir/mu-maildir-walk",
|
||||
test_mu_maildir_walk);
|
||||
g_test_add_func ("/mu-maildir/mu-maildir-walk-with-noupdate",
|
||||
test_mu_maildir_walk_with_noupdate);
|
||||
|
||||
/* get/set flags */
|
||||
g_test_add_func("/mu-maildir/mu-maildir-get-new-path-01",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH MU-EASY 1 "January 2012" "User Manuals"
|
||||
.TH MU-EASY 1 "May 2012" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
|
||||
|
@ -45,7 +45,8 @@ Normally, \fBmu index\fR visits all the directories under the top-level
|
|||
Maildir; however, you can exclude certain directories (say, the 'trash'
|
||||
or 'spam' folders) by creating a file called \fI.noindex\fR in the directory.
|
||||
When \fBmu\fR sees such a file, it will exclude this directory and its
|
||||
sub-directories from indexing.
|
||||
sub-directories from indexing. Also see \fB.noupdate\fR in the \fBmu-index\fR
|
||||
manpage.
|
||||
|
||||
.SH SEARCHING YOUR E-MAIL
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.TH MU-INDEX 1 "May 2011" "User Manuals"
|
||||
.TH MU-INDEX 1 "May 2012" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
.SH NAME
|
||||
|
||||
mu index \- index e-mail messages stored in Maildirs
|
||||
|
||||
|
@ -14,7 +14,7 @@ mu index \- index e-mail messages stored in Maildirs
|
|||
directories and storing the results in a Xapian database. The data can then be
|
||||
queried using
|
||||
.BR mu-find(1)
|
||||
\.
|
||||
\.
|
||||
|
||||
.B index
|
||||
understands Maildirs as defined by Daniel Bernstein for qmail(7). In addition,
|
||||
|
@ -33,6 +33,12 @@ directory and all of its subdirectories will be ignored. This can be useful to
|
|||
exclude certain directories from the indexing process, for example directories
|
||||
with spam-messages.
|
||||
|
||||
If there is a file called \fI.noupdate\fR in a directory, the contents of that
|
||||
directory and all of its subdirectories will be ignored, unless we do a full
|
||||
rebuild (with \fB--rebuild\fR). This can be useful to speed up things you have
|
||||
some maildirs that never change. Note that you can still search for these
|
||||
messages, this only affects updating the database.
|
||||
|
||||
The first run of \fBmu index\fR may take a few minutes if you have a lot of
|
||||
mail (ten thousands of messages). Fortunately, such a full scan needs to be
|
||||
done only once; after that it suffices to index the changes, which goes much
|
||||
|
|
Loading…
Reference in New Issue