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>