<<< Date Index >>>     <<< Thread Index >>>

Re: [Mutt] #920: Feature request with implementation: wildcards in



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

Changes (by brendan):

  * keywords:  IMAP,patch => patch
  * milestone:  => 2.0

Old description:

> {{{
> Package: mutt
> Version: 1.3.24i
> Severity: wishlist
>
> -- Please type your report below this line
> 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 */
>
> -- Build environment information
>
> (Note: This is the build environment installed on the system
> muttbug is run on.  Information may or may not match the environment
> used to build mutt.)
>
> - gcc version information
> gcc
> Reading specs from /usr/lib/gcc-lib/i386-linux/2.95.4/specs
> gcc version 2.95.4 20011006 (Debian prerelease)
>
> - CFLAGS
> -Wall -pedantic -g -O2
>
> -- Mutt Version Information
>
> Mutt 1.3.24i (2001-11-29)
> Copyright (C) 1996-2001 Michael R. Elkins and others.
> Mutt comes with ABSOLUTELY NO WARRANTY; for details type `mutt -vv'.
> Mutt is free software, and you are welcome to redistribute it
> under certain conditions; type `mutt -vv' for details.
>
> System: Linux 2.4.0 (i686) [using ncurses 5.2]
> Compile options:
> -DOMAIN
> +DEBUG
> -HOMESPOOL  +USE_SETGID  +USE_DOTLOCK  +DL_STANDALONE
> +USE_FCNTL  -USE_FLOCK
> -USE_POP  +USE_IMAP  -USE_GSS  -USE_SSL  -USE_SASL
> +HAVE_REGCOMP  -USE_GNU_REGEX
> +HAVE_COLOR  +HAVE_START_COLOR  +HAVE_TYPEAHEAD  +HAVE_BKGDSET
> +HAVE_CURS_SET  +HAVE_META  +HAVE_RESIZETERM
> +HAVE_PGP  -BUFFY_SIZE -EXACT_ADDRESS  -SUN_ATTACHMENT
> +ENABLE_NLS  -LOCALES_HACK  +HAVE_WC_FUNCS  +HAVE_LANGINFO_CODESET
> +HAVE_LANGINFO_YESEXPR
> +HAVE_ICONV  -ICONV_NONTRANS  +HAVE_GETSID  +HAVE_GETADDRINFO
> -ISPELL
> SENDMAIL="/usr/sbin/sendmail"
> MAILPATH="/var/mail"
> PKGDATADIR="/usr/local/share/mutt"
> SYSCONFDIR="/usr/local/etc"
> EXECSHELL="/bin/sh"
> -MIXMASTER
> To contact the developers, please mail to <mutt-dev@xxxxxxxx>.
> To report a bug, please use the flea(1) utility.
>

>
> >How-To-Repeat:
> >Fix:
> }}}

New description:

 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 */
 }}}

Comment:

 This should probably share code with `$imap_check_subscribed`

-- 
Ticket URL: <http://dev.mutt.org/trac/ticket/920#comment:2>