courier-imap unable to open INBOX
- Reply: Frank Leonhardt : "Re: courier-imap unable to open INBOX"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 16 Feb 2025 13:52:41 UTC
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. 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. Thanks, Benjamin