Jukka Salmi --> mutt-dev (2008-11-08 14:01:08 +0100):
> Hello,
>
> I'm seeing some recently introduced problems with Mutt, mainly regarding
> browsing IMAP folders (on Cyrus 2.1 and 2.2 IMAP servers; I didn't try
> other IMAP servers).
>
> Up to revision 5546 everything worked for me as expected. Starting with
> revision 5547 and up to 5553, browsing IMAP folders was broken (I was
> getting "Mailbox does not exist"); this was fixed with revision 5554.
> However, since 5554 my Mutt behaves strangely. Here's an example session:
>
> [what I type -> what Mutt prints, comments following # signs]
>
> c -> "---Mutt: =INBOX [Msgs:29 Post:1 Inc:5 3.1M]---..."
> "Open mailbox ('?' for list): =INBOX/Lists/NetBSD/current-users"
>
> # The separator printed is / which is wrong here (expecting dot!).
>
> tab -> "---Mutt: =INBOX [Msgs:29 Post:1 Inc:5 3.1M]---..."
> "Open mailbox: =INBOX.Lists.NetBSD.current-users"
>
> # This time the separator is the expected dot.
>
> tab -> "---Mutt: =INBOX [Msgs:29 Post:1 Inc:5 3.1M]---..."
> "Open mailbox: =INBOX.Lists.NetBSD.current-users"
>
> # Hmm, I hit tab again, but without effect. Previously this cause the
> # directory listing shown in the next step to be displayed.
>
> tab -> "-- Mutt: Directory [=INBOX.Lists.NetBSD.], File mask: !^\.[^.]"
> "1 IMAP current-users"
>
> # Everyting fine in this step.
>
> tab -> "-- Mutt: Mailboxes [5]"
>
> # The list of all mailboxes (as defined with the mailboxes command) is
> # shown, but %N is 0 for all of them even for those containing unread
> # and / or new messages.
>
> tab -> "-- Mutt: Directory [=INBOX.Lists.NetBSD.], File mask: !^\.[^.]"
> list of mailboxes beneath INBOX.Lists.NetBSD is shown
>
> # Everything fine here as well.
> # Further tabs loop over the last two lists described above as expected.
>
>
> Hmm, is anybody else seing this as well?
A patch (which is attached) I received off-list from TAKAHASHI Tamotsu
seems to fix the problems described above. Any comments?
BTW, the comment above Mutt's imap_fix_path() seems to indicate that
displaying '/' no matter what the real separator is is done
deliberately. Do I get this right?
Regards, Jukka
--
bashian roulette:
$ ((RANDOM%6)) || rm -rf ~
diff -r c2439fc68cd6 imap/imap_private.h
--- a/imap/imap_private.h Wed Oct 29 20:49:27 2008 -0700
+++ b/imap/imap_private.h Wed Nov 12 22:50:53 2008 +0900
@@ -271,7 +271,7 @@
void imap_error (const char* where, const char* msg);
IMAP_DATA* imap_new_idata (void);
void imap_free_idata (IMAP_DATA** idata);
-char* imap_fix_path (IMAP_DATA* idata, char* mailbox, char* path,
+char* imap_fix_path (IMAP_DATA* idata, const char* mailbox, char* path,
size_t plen);
void imap_cachepath(IMAP_DATA* idata, const char* mailbox, char* dest,
size_t dlen);
diff -r c2439fc68cd6 imap/util.c
--- a/imap/util.c Wed Oct 29 20:49:27 2008 -0700
+++ b/imap/util.c Wed Nov 12 22:50:53 2008 +0900
@@ -267,10 +267,15 @@
/* silly helper for mailbox name string comparisons, because of INBOX */
int imap_mxcmp (const char* mx1, const char* mx2)
{
+ char buf1[LONG_STRING];
+ char buf2[LONG_STRING];
+
if (!ascii_strcasecmp (mx1, "INBOX") && !ascii_strcasecmp (mx2, "INBOX"))
return 0;
- return mutt_strcmp (mx1, mx2);
+ imap_fix_path (NULL, mx1, buf1, sizeof (buf1));
+ imap_fix_path (NULL, mx2, buf2, sizeof (buf2));
+ return mutt_strcmp (buf1, buf2);
}
/* imap_pretty_mailbox: called by mutt_pretty_mailbox to make IMAP paths
@@ -283,14 +288,21 @@
int tlen;
int hlen = 0;
char home_match = 0;
+ char buf[STRING];
if (imap_parse_path (path, &target) < 0)
return;
+ imap_fix_path (NULL, target.mbox, buf, sizeof (buf));
+ FREE (&target.mbox);
+ target.mbox = safe_strdup (buf);
tlen = mutt_strlen (target.mbox);
/* check whether we can do '=' substitution */
if (mx_is_imap(Maildir) && !imap_parse_path (Maildir, &home))
{
+ imap_fix_path (NULL, home.mbox, buf, sizeof (buf));
+ FREE (&home.mbox);
+ home.mbox = safe_strdup (buf);
hlen = mutt_strlen (home.mbox);
if (tlen && mutt_account_match (&home.account, &target.account) &&
!mutt_strncmp (home.mbox, target.mbox, hlen))
@@ -390,7 +402,7 @@
* are not required to do this.
* Moreover, IMAP servers may dislike the path ending with the delimiter.
*/
-char *imap_fix_path (IMAP_DATA *idata, char *mailbox, char *path,
+char *imap_fix_path (IMAP_DATA *idata, const char *mailbox, char *path,
size_t plen)
{
int i = 0;
diff -r c2439fc68cd6 lib.c
--- a/lib.c Wed Oct 29 20:49:27 2008 -0700
+++ b/lib.c Wed Nov 12 22:50:53 2008 +0900
@@ -976,7 +976,8 @@
{
const char *fmt = "%s/%s";
- if (!*fname || (*dir && dir[strlen(dir)-1] == '/'))
+ if (!*fname || (*dir && dir[strlen(dir)-1] == '/')
+ || ((dir[0] == '+' || dir[0] == '=') && !dir[1]))
fmt = "%s%s";
snprintf (d, l, fmt, dir, fname);