Commit 5c16cf45 5c16cf454ffc05a340cbf8136c36e4cc1ed72904 by Sergey Poznyakoff

Use IMAP-stile wildcards in folder matchers by default.

* imap4d/imap4d.h: Include mailutils/imaputil.h
* imap4d/list.c: Use mu_folder_imap_match/mu_imap_wildmatch.
* imap4d/lsub.c: Likewise.
* imap4d/util.c (util_wcard_match): Move as to libmailutils
as mu_imap_wildmatch.
* include/mailutils/imaputil.h: New file.
* include/mailutils/Makefile.am (pkginclude_HEADERS): Add imaputil.h
* include/mailutils/folder.h (mu_folder_imap_match)
(mu_folder_glob_match): New protos.
* include/mailutils/imapio.h (mu_imap_flag_to_attribute)
(mu_imap_format_flags): Move to imaputil.h
* libmailutils/imapio/wildmatch.c: New file.
* libmailutils/imapio/sendflg.c: New file.
* libmailutils/imapio/Makefile.am (libimapio_la_SOURCES): Add
sendflg.c and wildmatch.c.
* libmailutils/imapio/flags.c (mu_imapio_send_flags): Move to
sendflg.c
* libmailutils/mailbox/folder.c (mu_folder_match): Rename to
mu_folder_glob_match.
(mu_folder_imap_match): New function.
(mu_folder_create_from_record): Use mu_folder_imap_match as the default
matcher.
* libmailutils/tests/fsfolder.c: Start command line options with a dash.
New option "-glob".  All uses changed.
* libproto/imap/select.c: Include imaputil.h
* mu/imap.c: Likewise.
1 parent b71b1bb1
......@@ -106,6 +106,7 @@
#include <mailutils/io.h>
#include <mailutils/prog.h>
#include <mailutils/imapio.h>
#include <mailutils/imaputil.h>
#include <mu_umaxtostr.h>
#include <muaux.h>
......
......@@ -19,12 +19,6 @@
#include <dirent.h>
#include <pwd.h>
static int
imap4d_match (const char *name, void *pat, int flags)
{
return util_wcard_match (name, pat, "/");
}
struct refinfo
{
char *refptr; /* Original reference */
......@@ -243,7 +237,8 @@ imap4d_list (struct imap4d_command *command, imap4d_tokbuf_t tok)
return io_completion_response (command, RESP_NO,
"The requested item could not be found.");
}
mu_folder_set_match (folder, imap4d_match);
/* Force the right matcher */
mu_folder_set_match (folder, mu_folder_imap_match);
memset (&refinfo, 0, sizeof refinfo);
......@@ -260,8 +255,8 @@ imap4d_list (struct imap4d_command *command, imap4d_tokbuf_t tok)
failure; it is not relevant whether the user's real INBOX resides
on this or some other server. */
if (!*ref && (imap4d_match ("INBOX", wcard, 0) == 0
|| imap4d_match ("inbox", wcard, 0) == 0))
if (!*ref && (mu_imap_wildmatch (wcard, "INBOX", delim[0]) == 0
|| mu_imap_wildmatch (wcard, "inbox", delim[0]) == 0))
io_untagged_response (RESP_NONE, "LIST (\\NoInferiors) NIL INBOX");
mu_folder_enumerate (folder, NULL, wcard, 0, 0, NULL,
......
......@@ -64,7 +64,7 @@ imap4d_lsub (struct imap4d_command *command, imap4d_tokbuf_t tok)
mu_iterator_current_kv (itr, (const void **)&name, (void**)&val);
if (util_wcard_match (name, pattern, delim) == 0)
if (mu_imap_wildmatch (pattern, name, delim[0]) == 0)
io_untagged_response (RESP_NONE, "LSUB () \"%s\" \"%s\"",
delim, name);
}
......
......@@ -566,63 +566,6 @@ util_localname ()
return localname;
}
/* Match STRING against the IMAP4 wildcard pattern PATTERN. */
#define WILD_FALSE 0
#define WILD_TRUE 1
#define WILD_ABORT 2
int
_wild_match (const char *expr, const char *name, char delim)
{
while (expr && *expr)
{
if (*name == 0 && *expr != '*')
return WILD_ABORT;
switch (*expr)
{
case '*':
while (*++expr == '*')
;
if (*expr == 0)
return WILD_TRUE;
while (*name)
{
int res = _wild_match (expr, name++, delim);
if (res != WILD_FALSE)
return res;
}
return WILD_ABORT;
case '%':
while (*++expr == '%')
;
if (*expr == 0)
return strchr (name, delim) ? WILD_FALSE : WILD_TRUE;
while (*name && *name != delim)
{
int res = _wild_match (expr, name++, delim);
if (res != WILD_FALSE)
return res;
}
return _wild_match (expr, name, delim);
default:
if (*expr != *name)
return WILD_FALSE;
expr++;
name++;
}
}
return *name == 0;
}
int
util_wcard_match (const char *name, const char *expr, const char *delim)
{
return _wild_match (expr, name, delim[0]) != WILD_TRUE;
}
/* Return the uindvalidity of a mailbox.
When a mailbox is selected, whose first message does not keep X-UIDVALIDITY
value, the uidvalidity is computed basing on the return of time(). Now,
......
......@@ -54,6 +54,7 @@ pkginclude_HEADERS = \
header.h\
imap.h\
imapio.h\
imaputil.h\
io.h\
iterator.h\
kwd.h\
......
......@@ -73,6 +73,12 @@ extern int mu_folder_set_match (mu_folder_t folder, mu_folder_match_fp pmatch);
extern int mu_folder_get_match (mu_folder_t folder,
mu_folder_match_fp *pmatch);
/* Two often used matchers: */
/* 1. The default: IMAP-style wildcards: */
extern int mu_folder_imap_match (const char *name, void *pattern, int flags);
/* 2. UNIX-style glob(7) wildcards: */
extern int mu_folder_glob_match (const char *name, void *pattern, int flags);
/* Notifications. */
extern int mu_folder_get_observable (mu_folder_t, mu_observable_t *);
......
......@@ -72,9 +72,6 @@ int mu_imapio_reply_string (mu_imapio_t io, size_t start, char **pbuf);
int mu_imapio_last_error (mu_imapio_t io);
void mu_imapio_clearerr (mu_imapio_t io);
int mu_imap_flag_to_attribute (const char *item, int *attr);
int mu_imap_format_flags (mu_stream_t str, int flags);
#ifdef __cplusplus
}
#endif
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _MAILUTILS_IMAPUTIL_H
# define _MAILUTILS_IMAPUTIL_H
#ifdef __cplusplus
extern "C" {
#endif
# include <mailutils/types.h>
int mu_imap_wildmatch (const char *pattern, const char *name, int delim);
int mu_imap_flag_to_attribute (const char *item, int *attr);
int mu_imap_format_flags (mu_stream_t str, int flags);
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_IMAPUTIL_H */
......@@ -31,9 +31,11 @@ libimapio_la_SOURCES = \
sendcmd.c\
sendcmdv.c\
sendcmde.c\
sendflg.c\
time.c\
trace.c\
transport.c\
wildmatch.c\
words.c\
xscript.c
......
......@@ -21,7 +21,7 @@
#include <mailutils/stream.h>
#include <mailutils/errno.h>
#include <mailutils/cstr.h>
#include <mailutils/sys/imapio.h>
#include <mailutils/imaputil.h>
static struct
{
......@@ -84,16 +84,3 @@ mu_imap_format_flags (mu_stream_t str, int flags)
return 0;
}
int
mu_imapio_send_flags (struct _mu_imapio *io, int flags)
{
int rc;
rc = mu_stream_write (io->_imap_stream, "(", 1, NULL);
if (rc)
return rc;
rc = mu_imap_format_flags (io->_imap_stream, flags);
if (rc == 0)
rc = mu_stream_write (io->_imap_stream, ")", 1, NULL);
return rc;
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <mailutils/types.h>
#include <mailutils/imapio.h>
#include <mailutils/stream.h>
#include <mailutils/imaputil.h>
#include <mailutils/sys/imapio.h>
int
mu_imapio_send_flags (struct _mu_imapio *io, int flags)
{
int rc;
rc = mu_stream_write (io->_imap_stream, "(", 1, NULL);
if (rc)
return rc;
rc = mu_imap_format_flags (io->_imap_stream, flags);
if (rc == 0)
rc = mu_stream_write (io->_imap_stream, ")", 1, NULL);
return rc;
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <string.h>
#include <mailutils/types.h>
#include <mailutils/imaputil.h>
/* Match STRING against the IMAP4 wildcard pattern PATTERN. */
#define WILD_FALSE 0
#define WILD_TRUE 1
#define WILD_ABORT 2
int
_wild_match (const char *pat, const char *name, char delim)
{
while (pat && *pat)
{
if (*name == 0 && *pat != '*')
return WILD_ABORT;
switch (*pat)
{
case '*':
while (*++pat == '*')
;
if (*pat == 0)
return WILD_TRUE;
while (*name)
{
int res = _wild_match (pat, name++, delim);
if (res != WILD_FALSE)
return res;
}
return WILD_ABORT;
case '%':
while (*++pat == '%')
;
if (*pat == 0)
return strchr (name, delim) ? WILD_FALSE : WILD_TRUE;
while (*name && *name != delim)
{
int res = _wild_match (pat, name++, delim);
if (res != WILD_FALSE)
return res;
}
return _wild_match (pat, name, delim);
default:
if (*pat != *name)
return WILD_FALSE;
pat++;
name++;
}
}
return *name == 0;
}
int
mu_imap_wildmatch (const char *pattern, const char *name, int delim)
{
return _wild_match (pattern, name, delim) != WILD_TRUE;
}
......@@ -37,6 +37,7 @@
#include <mailutils/errno.h>
#include <mailutils/property.h>
#include <mailutils/mailbox.h>
#include <mailutils/imaputil.h>
#include <mailutils/sys/folder.h>
......@@ -48,11 +49,17 @@ static int is_known_folder (mu_url_t, mu_folder_t *);
static struct mu_monitor folder_lock = MU_MONITOR_INITIALIZER;
int
mu_folder_match (const char *name, void *pattern, int flags)
mu_folder_glob_match (const char *name, void *pattern, int flags)
{
return fnmatch (pattern, name[0] == '/' ? name + 1 : name, 0);
}
int
mu_folder_imap_match (const char *name, void *pattern, int flags)
{
return mu_imap_wildmatch (pattern, name, '/');
}
/* A folder could be remote (IMAP), or local(a spool directory) like $HOME/Mail
etc .. We maintain a list of known folders to avoid creating multiple
folders for the same URL. So, when mu_folder_create is called we check if
......@@ -126,7 +133,7 @@ mu_folder_create_from_record (mu_folder_t *pfolder, mu_url_t url,
if (status == 0)
{
if (!folder->_match)
folder->_match = mu_folder_match;
folder->_match = mu_folder_imap_match;
*pfolder = folder;
folder->ref++;
/* Put on the internal list of known folders. */
......
......@@ -172,7 +172,7 @@ usage ()
struct command *cp;
mu_printf (
"usage: %s [debug=SPEC] name=URL OP ARG [ARG...] [OP ARG [ARG...]...]\n",
"usage: %s [-debug=SPEC] -name=URL [-sort] [-glob] OP ARG [ARG...] [OP ARG [ARG...]...]\n",
mu_program_name);
mu_printf ("OPerations and corresponding ARGuments are:\n");
for (cp = comtab; cp->verb; cp++)
......@@ -211,6 +211,7 @@ main (int argc, char **argv)
int rc;
mu_folder_t folder;
char *fname = NULL;
int glob_option = 0;
mu_set_program_name (argv[0]);
mu_registrar_record (&test_record);
......@@ -223,12 +224,14 @@ main (int argc, char **argv)
for (i = 1; i < argc; i++)
{
if (strncmp (argv[i], "debug=", 6) == 0)
mu_debug_parse_spec (argv[i] + 6);
else if (strncmp (argv[i], "name=", 5) == 0)
fname = argv[i] + 5;
else if (strcmp (argv[i], "sort") == 0)
if (strncmp (argv[i], "-debug=", 7) == 0)
mu_debug_parse_spec (argv[i] + 7);
else if (strncmp (argv[i], "-name=", 6) == 0)
fname = argv[i] + 6;
else if (strcmp (argv[i], "-sort") == 0)
sort_option = 1;
else if (strcmp (argv[i], "-glob") == 0)
glob_option = 1;
else
break;
}
......@@ -262,6 +265,9 @@ main (int argc, char **argv)
return 1;
}
if (glob_option)
mu_folder_set_match (folder, mu_folder_glob_match);
while (i < argc)
{
char *comargs[2];
......
......@@ -26,7 +26,7 @@ mkdir dir/subdir
> dir/subdir/file
> dir/subdir/baz.mbox
fsfolder name=dir sort dnl
fsfolder -name=dir -sort dnl
list "" "*" dnl
list subdir "*" dnl
list "" "*.mbox" dnl
......
......@@ -19,17 +19,17 @@ AT_KEYWORDS([fsfolder folder-subscribe])
AT_CHECK([
mkdir dir
fsfolder name=dir sort lsub "" "*"
fsfolder name=dir subscribe foo
fsfolder name=dir sort lsub "" "*"
fsfolder name=dir subscribe baz subscribe foo/baz subscribe foo/bar
fsfolder name=dir sort lsub "" "*"
fsfolder name=dir sort lsub foo "*"
fsfolder name=dir sort lsub "" 'foo*'
fsfolder name=dir unsubscribe baz
fsfolder name=dir sort lsub "" "*"
fsfolder name=dir unsubscribe foo
fsfolder name=dir sort lsub "" "*"
fsfolder -name=dir -sort lsub "" "*"
fsfolder -name=dir subscribe foo
fsfolder -name=dir -sort lsub "" "*"
fsfolder -name=dir subscribe baz subscribe foo/baz subscribe foo/bar
fsfolder -name=dir -sort lsub "" "*"
fsfolder -name=dir -sort lsub foo "*"
fsfolder -name=dir -sort lsub "" 'foo*'
fsfolder -name=dir unsubscribe baz
fsfolder -name=dir -sort lsub "" "*"
fsfolder -name=dir unsubscribe foo
fsfolder -name=dir -sort lsub "" "*"
],
[0],
[listing subscriptions for '' '*'
......
......@@ -20,10 +20,10 @@ AT_KEYWORDS([fsfolder folder-rename])
AT_CHECK([
mkdir dir
> dir/foo
fsfolder name=dir rename foo bar
fsfolder name=dir list "" "*"
fsfolder -name=dir rename foo bar
fsfolder -name=dir list "" "*"
> dir/baz
fsfolder name=dir rename bar baz
fsfolder -name=dir rename bar baz
],
[0],
[renaming foo to bar
......
......@@ -25,6 +25,7 @@
#include <mailutils/assoc.h>
#include <mailutils/stream.h>
#include <mailutils/imap.h>
#include <mailutils/imaputil.h>
#include <mailutils/sys/imap.h>
static int
......
......@@ -26,6 +26,7 @@
#include <mailutils/mailutils.h>
#include <mailutils/imap.h>
#include <mailutils/imapio.h>
#include <mailutils/imaputil.h>
#include "mu.h"
#include "argp.h"
#include "xalloc.h"
......