From 1494923472c1b009c0b4390270887f54fbaf9369 Mon Sep 17 00:00:00 2001 From: djcb Date: Sat, 19 Nov 2016 16:17:43 +0200 Subject: [PATCH] mu: fix broken clear_links clear_links as used for the --clear-links option had some broken filename generation, causing garbage data at the end. Clean up this old code, and fix this problem as a side-effect. Fixes issue #951. --- lib/mu-maildir.c | 90 +++++++++++++++++++++++++----------------------- man/mu-find.1 | 15 ++++---- 2 files changed, 54 insertions(+), 51 deletions(-) diff --git a/lib/mu-maildir.c b/lib/mu-maildir.c index 846a5a86..e737a865 100644 --- a/lib/mu-maildir.c +++ b/lib/mu-maildir.c @@ -583,77 +583,79 @@ mu_maildir_walk (const char *path, MuMaildirWalkMsgCallback cb_msg, static gboolean -clear_links (const gchar* dirname, DIR *dir, GError **err) +clear_links (const char *path, DIR *dir) { - struct dirent *entry; - gboolean rv; + gboolean rv; + struct dirent *dentry; - rv = TRUE; + rv = TRUE; errno = 0; - while ((entry = readdir (dir))) { - const char *fp; - char *fullpath; - unsigned char d_type; - guint len; + while ((dentry = readdir (dir))) { - /* ignore empty, dot thingies */ - if (entry->d_name[0] == '\0' || entry->d_name[0] == '.') - continue; + guint8 d_type; + char *fullpath; - /* we have to copy the buffer from fullpath_s, because - * it returns a static buffer and we are - * recursive*/ - fp = mu_str_fullpath_s (dirname, entry->d_name); - len = strlen(fp); - fullpath = g_newa (char, len + 1); - strncpy (fullpath, fp, len); + if (dentry->d_name[0] == '.') + continue; /* ignore .,.. other dotdirs */ - d_type = GET_DTYPE (entry, fullpath); - - /* ignore non-links / non-dirs */ - if (d_type != DT_LNK && d_type != DT_DIR) - continue; + fullpath = g_build_path ("/", path, dentry->d_name, NULL); + d_type = GET_DTYPE (dentry, fullpath); if (d_type == DT_LNK) { - if (unlink (fullpath) != 0) { - /* don't use err */ - g_warning ("error unlinking %s: %s", - fullpath, strerror(errno)); + if (unlink (fullpath) != 0 ) { + g_warning ("error unlinking %s: %s", + fullpath, strerror(errno)); rv = FALSE; } - } else /* DT_DIR, see check before*/ - rv = mu_maildir_clear_links (fullpath, err); + } else if (d_type == DT_DIR) { + DIR *subdir; + subdir = opendir (fullpath); + if (!subdir) { + g_warning ("failed to open dir %s: %s", + fullpath, strerror(errno)); + rv = FALSE; + goto next; + } + + if (!clear_links (fullpath, subdir)) + rv = FALSE; + + closedir (subdir); + } + + next: + g_free (fullpath); } - if (errno != 0) - mu_util_g_set_error (err, MU_ERROR_FILE, - "file error: %s", strerror(errno)); - - return (rv == FALSE && errno == 0); + return rv; } - gboolean -mu_maildir_clear_links (const gchar* path, GError **err) +mu_maildir_clear_links (const char *path, GError **err) { - DIR *dir; - gboolean rv; + DIR *dir; + gboolean rv; g_return_val_if_fail (path, FALSE); dir = opendir (path); - if (!dir) - return mu_util_g_set_error (err, MU_ERROR_FILE_CANNOT_OPEN, - "failed to open %s: %s", path, - strerror(errno)); + if (!dir) { + g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE_CANNOT_OPEN, + "failed to open %s: %s", path, strerror(errno)); + return FALSE; + } + + rv = clear_links (path, dir); - rv = clear_links (path, dir, err); closedir (dir); return rv; } + + + MuFlags mu_maildir_get_flags_from_path (const char *path) { diff --git a/man/mu-find.1 b/man/mu-find.1 index 8d534ae3..f9639f1d 100644 --- a/man/mu-find.1 +++ b/man/mu-find.1 @@ -362,7 +362,7 @@ The default is \fBplain\fR, i.e normal output with one line per message. \fBlinks\fR outputs the results as a maildir with symbolic links to the found messages. This enables easy integration with mail-clients (see below for more -information). See \fB\-\-linksdir\fR and \fB\-\-clearlinks\fR below. +information). \fBxml\fR formats the search results as XML. @@ -375,13 +375,14 @@ is meant for for debugging purposes. .TP \fB\-\-linksdir\fR \fR=\fI\fR and \fB\-c\fR, \fB\-\-clearlinks\fR output the results as a maildir with symbolic links to the found -messages. This enables easy integration with mail-clients (see below for more -information). \fBmu\fR will create the maildir if it does not exist yet. +messages. This enables easy integration with mail-clients (see below +for more information). \fBmu\fR will create the maildir if it does not +exist yet. -If you specify \fB\-\-clearlinks\fR, all existing symlinks will be cleared -from the target maildir; this allows for re-use of the same directory. An -alternative would be to delete the target directory before, but this has a big -chance of accidentally removing something that should not be removed. +If you specify \fB\-\-clearlinks\fR, all existing symlinks will be +cleared from the target directories; this allows for re-use of the +same maildir. However, this option will delete any symlink it finds, +so be careful. .nf $ mu find grolsch --linksdir=~/Maildir/search --clearlinks