Ticket #920 (new enhancement)

Opened 7 years ago

Last modified 20 months ago

Feature request with implementation: wildcards in 'mailboxes' list for IMAP folders

Reported by: ntyni+mutt@… Owned by: mutt-dev
Priority: trivial Milestone: 2.0
Component: IMAP Version: 1.3.24i
Keywords: patch Cc:

Description (last modified by brendan) (diff)

Here's a way to enable wildcards in IMAP folder names for the 'mailboxes' variable. The wildcards are expanded by the IMAP server (LIST or LSUB, depending on the corresponding option), when the folder is checked for the first time. The 'imap_passive' option is honoured.

I'd be very glad if something like this made its way to the official release.

Patch against stock 1.3.24i:

--- ./doc/manual.sgml	2001/12/16 21:26:08	1.1
+++ ./doc/manual.sgml	2001/12/16 21:29:54
@@ -1235,6 +1235,11 @@
 name="&dollar;folder"> and <ref id="spoolfile" name="&dollar;spoolfile">)
 should be executed before the <tt/mailboxes/ command.
 
+<bf/Note:/ you can specify wildcards (``%'' and ``*'') in IMAP mailbox names.
+They are expanded by the server when the mailbox is checked for the first 
+time.  Currently there is no way to refresh the list afterwards except by 
+restarting Mutt.
+
 <sect1>User defined headers<label id="my_hdr">
 <p>
 Usage:<newline>
--- ./imap/imap.c	2001/12/16 15:53:23	1.1
+++ ./imap/imap.c	2001/12/16 16:48:31
@@ -32,6 +32,7 @@
 #ifdef USE_SSL
 # include "mutt_ssl.h"
 #endif
+#include "buffy.h"
 
 #include <unistd.h>
 #include <ctype.h>
@@ -1438,3 +1439,88 @@
   FREE (&mx.mbox);
   return -1;
 }
+
+int imap_expand_mailboxes() {
+  CONNECTION *conn;
+  IMAP_DATA *idata = NULL;
+  BUFFY *tmp;
+  BUFFY *tmp2;
+  char* list_word = NULL;
+  char buf[LONG_STRING];
+  char mbox[LONG_STRING];
+  char mbox_unquoted[LONG_STRING];
+  int connflags = 0;
+  IMAP_MBOX mx;
+  int noselect, noinferiors;
+  int found=0;
+  int first;
+  char delim;
+
+  /* If imap_passive is set, don't open a connection to expand the mailboxes */
+  if (option (OPTIMAPPASSIVE))
+  	connflags = M_IMAP_CONN_NONEW;
+
+  for (tmp=Incoming; tmp; tmp=tmp->next) {
+    do {
+  	if (imap_parse_path (tmp->path , &mx))
+		break;
+	if (!strchr(tmp->path, '*') && !strchr(tmp->path, '%'))
+		break;
+	found++;
+  	if (!idata && !(idata = imap_conn_find (&(mx.account), connflags)))
+  	{
+   		FREE (&mx.mbox);
+  		return -1;
+  	}
+  	conn = idata->conn;
+
+  	imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
+  	FREE(&mx.mbox);
+
+  	imap_munge_mbox_name (mbox, sizeof(mbox), buf);
+  	strfcpy (mbox_unquoted, buf, sizeof (mbox_unquoted));
+
+  	snprintf (buf, sizeof(buf), "%s \"\" %s",
+    		option (OPTIMAPLSUB) ? "LSUB" : "LIST", mbox);
+
+  	imap_cmd_start (idata, buf);
+
+	first = 1;
+  	do {
+    		if (imap_parse_list_response(idata, &list_word, &noselect, 
+			&noinferiors, &delim))
+      			break;
+
+    		if (list_word) {
+	    		imap_unmunge_mbox_name (list_word);
+    	    		imap_qualify_path (buf, sizeof(buf), &mx, list_word);
+
+	    		if (noselect)
+		    		break;
+	    		for (tmp2 = Incoming; tmp2; tmp2 = tmp2->next) {
+		    		if (mutt_strcmp (buf, tmp2->path) == 0)
+			    		break;
+	    		}
+	    		if (!tmp2) {
+				if (first) {
+					tmp2 = tmp;
+					safe_free((void **) (tmp->path));
+					first = 0;
+				} else {
+		     			tmp2 = (BUFFY *) safe_calloc (1, sizeof (BUFFY));
+					tmp2->next = tmp->next;
+					tmp->next = tmp2;
+				}
+		     		tmp2->path = safe_strdup (buf);
+	    			tmp2->new = 0;
+	    			tmp2->notified = 1;
+	    			tmp2->newly_created = 0;
+				tmp = tmp2;
+	    		}
+    		}
+  	} while (mutt_strncmp(idata->cmd.seq, idata->cmd.buf, SEQLEN));
+    } while(0);
+  }
+  return found;
+}
+
 
 
 
--- ./imap/imap.h	2001/12/16 16:38:32	1.1
+++ ./imap/imap.h	2001/12/16 16:38:47
@@ -47,6 +47,7 @@
 
 void imap_allow_reopen (CONTEXT *ctx);
 void imap_disallow_reopen (CONTEXT *ctx);
+int imap_expand_mailboxes(void);
 
 /* browse.c */
 int imap_browse (char* path, struct browser_state* state);
--- ./buffy.c	2001/12/16 16:34:38	1.1
+++ ./buffy.c	2001/12/16 17:03:08
@@ -39,6 +39,10 @@
 static short BuffyCount = 0;	/* how many boxes with new mail */
 static short BuffyNotify = 0;	/* # of unnotified new boxes */
 
+#ifdef USE_IMAP
+int done_expand=0;
+#endif
+
 #ifdef BUFFY_SIZE
 
 /* Find the last message in the file. 
@@ -235,6 +239,10 @@
   /* update postponed count as well, on force */
   if (force)
     mutt_update_num_postponed ();
+  if (!done_expand && imap_expand_mailboxes() >= 0) {
+	done_expand = 1;
+  }
+	
 #endif
 
   /* fastest return if there are no mailboxes */

Change History

Changed 22 months ago by rado

Move to IMAP category

Changed 20 months ago by brendan

  • keywords patch added; IMAP,patch removed
  • description modified (diff)
  • milestone set to 2.0

This should probably share code with $imap_check_subscribed

Note: See TracTickets for help on using tickets.