[Dovecot] LIST problem with Dovecot1.1beta10
Dean Brooks
dean at iglou.com
Tue Dec 4 21:47:18 EET 2007
On Tue, Dec 04, 2007 at 07:34:37PM +0200, Timo Sirainen wrote:
> On Tue, 2007-12-04 at 12:12 -0500, Dean Brooks wrote:
> > However, no matter what configuration changes I make, Dovecot refuses
> > to list a filesystem mailbox unless you specify a wildcard:
> >
> > x list "" Sent
> > x OK List completed.
> >
> > x list "" Sent*
> > * LIST (\NoInferiors \UnMarked) "/" "Sent"
> > x OK List completed.
> >
> > Were there any changes to the filesystem listing code? We're on NFS
> > filesystem if it makes any difference.
>
> That might explain it, but I can't think of any change that could have
> broken this.
Found it.
It affects anyone under Solaris 8 , and probably all other versions of Solaris.
In src/list/mailbox-list-fs-iter.c, in the function fs_list_dir_next(),
the following code near the end of the function is the culprit:
if (i_strocpy(dir->dirent.d_name, fname,
sizeof(dir->dirent.d_name)) < 0) {
/* name too large.. shouldn't happen. */
continue;
}
To fix it, I changed it to:
if (i_strocpy(dir->dirent.d_name, fname, MAXNAMLEN) < 0) {
/* name too large.. shouldn't happen. */
continue;
}
It appears that sizeof(dir->dirent.d_name) always returns "1" under
Solaris. Indeed, when I do a "man dirent", I see this:
The dirent structure is defined:
struct dirent {
ino_t d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name[1];
};
The field d_name
is the beginning of the character array giving the name of
the directory entry. This name is null terminated and may
have at most MAXNAMLEN characters. This results in file
system independent directory entries being variable length
entities.
Turns out this is a common dirent portability issue that affects a
few operating systems, including Solaris. I googled around and
found other authors who have done crazy stuff like this:
#ifdef BROKEN_ONE_BYTE_DIRENT_D_NAME
strcpy(dirent->d_name, filename, MAXPATHLEN);
#else
strcpy(dirent->d_name, filename, sizeof(dirent->d_name));
#endif
There is probably a cleaner way to deal with this though. Anyway, it
something that needs to be dealt with. From what I can tell, this is
the only place in Dovecot where a sizeof() is done on d_name.
--
Dean Brooks
dean at iglou.com
More information about the dovecot
mailing list