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 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; errno = 0;
while ((entry = readdir (dir))) {
const char *fp; while ((dentry = readdir (dir))) {
char *fullpath;
unsigned char d_type;
guint len;
/* ignore empty, dot thingies */ guint8 d_type;
if (entry->d_name[0] == '\0' || entry->d_name[0] == '.') char *fullpath;
continue;
/* we have to copy the buffer from fullpath_s, because if (dentry->d_name[0] == '.')
* it returns a static buffer and we are continue; /* ignore .,.. other dotdirs */
* recursive*/
fp = mu_str_fullpath_s (dirname, entry->d_name);
len = strlen(fp);
fullpath = g_newa (char, len + 1);
strncpy (fullpath, fp, len);
d_type = GET_DTYPE (entry, fullpath); fullpath = g_build_path ("/", path, dentry->d_name, NULL);
d_type = GET_DTYPE (dentry, fullpath);
/* ignore non-links / non-dirs */
if (d_type != DT_LNK && d_type != DT_DIR)
continue;
if (d_type == DT_LNK) { if (d_type == DT_LNK) {
if (unlink (fullpath) != 0) { if (unlink (fullpath) != 0 ) {
/* don't use err */ g_warning ("error unlinking %s: %s",
g_warning ("error unlinking %s: %s", fullpath, strerror(errno));
fullpath, strerror(errno));
rv = FALSE; rv = FALSE;
} }
} else /* DT_DIR, see check before*/ } else if (d_type == DT_DIR) {
rv = mu_maildir_clear_links (fullpath, err); 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) return rv;
mu_util_g_set_error (err, MU_ERROR_FILE,
"file error: %s", strerror(errno));
return (rv == FALSE && errno == 0);
} }
gboolean gboolean
mu_maildir_clear_links (const gchar* path, GError **err) mu_maildir_clear_links (const char *path, GError **err)
{ {
DIR *dir; DIR *dir;
gboolean rv; gboolean rv;
g_return_val_if_fail (path, FALSE); g_return_val_if_fail (path, FALSE);
dir = opendir (path); dir = opendir (path);
if (!dir) if (!dir) {
return mu_util_g_set_error (err, MU_ERROR_FILE_CANNOT_OPEN, g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE_CANNOT_OPEN,
"failed to open %s: %s", path, "failed to open %s: %s", path, strerror(errno));
strerror(errno)); return FALSE;
}
rv = clear_links (path, dir);
rv = clear_links (path, dir, err);
closedir (dir); closedir (dir);
return rv; return rv;
} }
MuFlags MuFlags
mu_maildir_get_flags_from_path (const char *path) 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 \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 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. \fBxml\fR formats the search results as XML.
@ -375,13 +375,14 @@ is meant for for debugging purposes.
.TP .TP
\fB\-\-linksdir\fR \fR=\fI<dir>\fR and \fB\-c\fR, \fB\-\-clearlinks\fR \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 output the results as a maildir with symbolic links to the found
messages. This enables easy integration with mail-clients (see below for more messages. This enables easy integration with mail-clients (see below
information). \fBmu\fR will create the maildir if it does not exist yet. 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 If you specify \fB\-\-clearlinks\fR, all existing symlinks will be
from the target maildir; this allows for re-use of the same directory. An cleared from the target directories; this allows for re-use of the
alternative would be to delete the target directory before, but this has a big same maildir. However, this option will delete any symlink it finds,
chance of accidentally removing something that should not be removed. so be careful.
.nf .nf
$ mu find grolsch --linksdir=~/Maildir/search --clearlinks $ mu find grolsch --linksdir=~/Maildir/search --clearlinks