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.
This commit is contained in:
djcb 2016-11-19 16:17:43 +02:00
parent 3aee179bf1
commit 1494923472
2 changed files with 54 additions and 51 deletions

View File

@ -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)
{

View File

@ -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<dir>\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