Re: courier-imap unable to open INBOX
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 16 Feb 2025 17:20:49 UTC
On 16/02/25 14:39, Benjamin Lutz wrote:
> Hello,
>
> Recently I encountered a problem with courier-imap an two different
> machines. When trying to open the INBOX, courier-imap's imapd would
> answer with:
>
> NO Unable to open this mailbox.
>
> The existance or absence of the problem can be quickly tested with:
>
> $ echo 'a SELECT INBOX' | imapd ~/Maildir
>
> I'm running FreeBSD-13.4 and 14.2 on the affected machines, and courier-
> imap is installed via ports, the only enabled CONFIG options are INOTIFY
> and IPV6.
>
> The first thing I tried is to recompile the port and all dependencies,
> but that didn't solve the problem.
Hi!
I've been experiencing issues with imap too, as soon as I updated
libunistring, reported it here:
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=283588
downgrading libunistring to 1.2 "fixed" the issue for me. So I suspect
this is somewhat related, but have not been able to diagnose the issue
so far.
Also, up to now I was not even sure it was not a local issue I was the
only one having!
>
> So I dug into courier-imap's source code, finally coming to this line in
> maildircreate.c:149:
>
> if (stat( info->tmpname, &stat_buf) == 0)
>
> What the code is trying to do here is to create a temporary file; it
> runs stat(2) on info->tmpname, expecting a -1 return value and errno set
> to ENOENT, because the file shouldn't currently exist. However, errno is
> not set to ENOENT, which finally results in the "NO Unable to open this
> mailbox." error.
>
> In order to better understand it, I built courier-imap with debugging
> flags and added some debugging code around the line above:
>
> errno=-999;
> int stat_retval=stat( info->tmpname, &stat_buf);
> fprintf(stderr, "stat=%p, stat(%p, %p), stat_retval=%d, errno=%d,
> strerror(errno)=%s\n", stat, info->tmpname, &stat_buf,
> stat_retval, errno, strerror(errno));
> if (stat_retval == 0)
>
> When SELECTing the INBOX now, I get:
>
> stat=0x823bc4f70, stat(0x2f67a4269000, 0x820949b40), stat_retval=-1,
> errno=-999, strerror(errno)=Unknown error: -999
> a NO Unable to open this mailbox.
>
> So errno isn't changed by stat(2) (confirmed with other values than
> -999). This has me rather perplexed. How can a stat(2) call not set
> errno? As far as I can tell using GDB, that stat() call really is a call
> into libc, not some other function that might shadow stat(2).
>
> I've extracted maildircreate.c into a separate project to build a
> minimal test, but when I just call the function in question
> (maildir_tmpcreate_fd, which the line above is from), then stat(2) works
> as expected, i.e. errno is set to 2.
>
> Can anyone give me some explanations for the observed behavior? Or even
> just some ideas for analyzing it further?
>
> The current stop-gap measure I've implemented to make courier-imap work
> again is the following patch:
>
> --- libs/maildir/maildircreate.c.orig 2022-05-23
> 11:00:05.000000000 +0200
> +++ libs/maildir/maildircreate.c 2025-02-14
> 22:19:39.434539000 +0100
> @@ -146,6 +146,7 @@
> strcat(info->tmpname, hostname);
> strcat(info->tmpname, len_buf);
>
> + errno=ENOENT;
> if (stat( info->tmpname, &stat_buf) == 0)
> {
> maildir_tmpcreate_free(info);
>
> But obviously, that's not exactly a reliable solution.
>
As I said, reverting libunistring to 1.2 "fixes" it for me, so it could
be libunistring interfering in some way with stat?
--
Guido Falsi <madpilot@FreeBSD.org>