Commit 33a5d852 33a5d85239028bc3e34eec59909253d12d5434f4 by Sergey Poznyakoff

Share folder implementation between mbox, mh and maildir. Fix mu_folder_delete.

* include/mailutils/folder.h (_mu_fsfolder_init): New proto.
* include/mailutils/mailbox.h (mu_mailbox_create_at): New proto.
* libmailutils/mailbox/mailbox.c (mu_mailbox_create_at): New function.
* libmailutils/mailbox/Makefile.am (libmailbox_la_SOURCES): Add fsfolder.c
* libmailutils/mailbox/folder.c (mu_folder_delete): If folder does
not provide its own method for deletion, use mu_mailbox_remove.
(mu_folder_open, mu_folder_close, mu_folder_enumerate)
(mu_folder_lsub, mu_folder_subscribe, mu_folder_unsubscribe)
(mu_folder_rename): Return EINVAL if folder is NULL.
(mu_folder_match): Bugfix: don't pass folder flags to fnmatch.
* libmailutils/mailbox/fsfolder.c: New file. Implementation of
file-system based folders.
* libmailutils/mailbox/mailbox (_create_mailbox0): Propagate error
return from mu_registrar_lookup_url.
* libmailutils/tests/fsfolder00.at: New test case.
* libmailutils/tests/fsfolder01.at: New test case.
* libmailutils/tests/fsfolder02.at: New test case.
* libmailutils/tests/Makefile.am (noinst_PROGRAMS): Add fsfolder.
(TESTSUITE_AT): Add fsfolder tests.
* libmailutils/tests/testsuite.at: Include fsfolder tests.

* libproto/mbox/folder.c: Use fsfolder.
(_mh_is_scheme): Check file even if scheme matches.
* libproto/maildir/folder.c: Likewise.
(_maildir_is_scheme): Check file even if scheme matches.
* libproto/mh/folder.c: Likewise.

* testsuite/fldel.c: New file.
* testsuite/Makefile.am (noinst_PROGRAMS): Buld fldel.
1 parent a8374536
......@@ -92,6 +92,8 @@ extern int mu_folder_get_property (mu_folder_t, mu_property_t *);
extern int mu_folder_decrement (mu_folder_t);
extern void mu_list_response_free (void *data);
int _mu_fsfolder_init (mu_folder_t folder);
#ifdef __cplusplus
}
......
......@@ -43,6 +43,8 @@ extern int mu_mailbox_create_from_record (mu_mailbox_t *pmbox,
mu_record_t record,
const char *name);
extern int mu_mailbox_create_default (mu_mailbox_t *, const char *);
extern int mu_mailbox_create_at (mu_mailbox_t *pmbox, mu_folder_t folder,
const char *name);
extern void mu_mailbox_destroy (mu_mailbox_t *);
......
......@@ -25,6 +25,7 @@ libmailbox_la_SOURCES = \
body.c\
envelope.c\
folder.c\
fsfolder.c\
hdrfirst.c\
hdritr.c\
header.c\
......
......@@ -36,6 +36,7 @@
#include <mailutils/url.h>
#include <mailutils/errno.h>
#include <mailutils/property.h>
#include <mailutils/mailbox.h>
#include <mailutils/sys/folder.h>
......@@ -49,7 +50,7 @@ static struct mu_monitor folder_lock = MU_MONITOR_INITIALIZER;
int
mu_folder_match (const char *name, void *pattern, int flags)
{
return fnmatch (pattern, name[0] == '/' ? name + 1 : name, flags);
return fnmatch (pattern, name[0] == '/' ? name + 1 : name, 0);
}
/* A folder could be remote (IMAP), or local(a spool directory) like $HOME/Mail
......@@ -249,7 +250,9 @@ mu_folder_get_property (mu_folder_t folder, mu_property_t *prop)
int
mu_folder_open (mu_folder_t folder, int flags)
{
if (folder == NULL || folder->_open == NULL)
if (folder == NULL)
return EINVAL;
if (folder->_open == NULL)
return ENOSYS;
return folder->_open (folder, flags);
}
......@@ -257,7 +260,9 @@ mu_folder_open (mu_folder_t folder, int flags)
int
mu_folder_close (mu_folder_t folder)
{
if (folder == NULL || folder->_close == NULL)
if (folder == NULL)
return EINVAL;
if (folder->_close == NULL)
return ENOSYS;
return folder->_close (folder);
}
......@@ -381,8 +386,10 @@ mu_folder_enumerate (mu_folder_t folder, const char *name,
mu_folder_enumerate_fp enumfun, void *enumdata)
{
int status;
if (folder == NULL || folder->_list == NULL)
if (folder == NULL)
return EINVAL;
else if (folder->_list == NULL)
return ENOSYS;
else
{
mu_list_t list = NULL;
......@@ -412,7 +419,9 @@ mu_folder_lsub (mu_folder_t folder, const char *dirname, const char *basename,
{
int status;
if (folder == NULL || folder->_lsub == NULL)
if (folder == NULL)
return EINVAL;
else if (folder->_lsub == NULL)
return ENOSYS;
else
{
......@@ -428,31 +437,64 @@ mu_folder_lsub (mu_folder_t folder, const char *dirname, const char *basename,
int
mu_folder_subscribe (mu_folder_t folder, const char *name)
{
if (folder == NULL || folder->_subscribe == NULL)
if (folder == NULL)
return EINVAL;
if (folder->_subscribe == NULL)
return ENOSYS;
return folder->_subscribe (folder, name);
}
int
mu_folder_unsubscribe (mu_folder_t folder, const char *name)
{
if (folder == NULL || folder->_unsubscribe == NULL)
if (folder == NULL)
return EINVAL;
if (folder->_unsubscribe == NULL)
return ENOSYS;
return folder->_unsubscribe (folder, name);
}
int
mu_folder_delete (mu_folder_t folder, const char *name)
{
if (folder == NULL || folder->_delete == NULL)
return ENOSYS;
return folder->_delete (folder, name);
int rc;
if (folder == NULL)
return EINVAL;
if (folder->_delete)
rc = folder->_delete (folder, name);
else
{
/* If there is no folder-specific _delete method, then try to create the
mailbox and call mailbox delete (remove) method. This is necessary
because certain types of mailboxes share a common folder (e.g. mbox,
maildir and mh all use filesystem folder), but have a different
internal structure. Supplying mu_folder_t with a knowledge of mailbox
internals will harm separation of concerns. On the other hand,
removing something without looking into it may well yield undesired
results. For example, a MH mailbox can hold another mailboxes, i.e.
be a folder itself. Removing it blindly would result in removing
these mailboxes as well, which is clearly not indended.
To solve this folder and mailbox delete methods are tightly paired,
but without looking into each-others internal mechanisms. */
mu_mailbox_t mbox;
rc = mu_mailbox_create_at (&mbox, folder, name);
if (rc == 0)
{
rc = mu_mailbox_remove (mbox);
mu_mailbox_destroy (&mbox);
}
}
return rc;
}
int
mu_folder_rename (mu_folder_t folder, const char *oldname, const char *newname)
{
if (folder == NULL || folder->_rename == NULL)
if (folder == NULL)
return EINVAL;
if (folder->_rename == NULL)
return ENOSYS;
return folder->_rename (folder, oldname, newname);
}
......
......@@ -41,6 +41,7 @@
#include <mailutils/util.h>
#include <mailutils/sys/mailbox.h>
#include <mailutils/sys/folder.h>
#include <mailutils/sys/url.h>
/* Mailbox-specific flags */
......@@ -76,7 +77,8 @@ mailbox_folder_create (mu_mailbox_t mbox, const char *name,
int
_mailbox_create_from_record (mu_mailbox_t *pmbox,
mu_record_t record,
mu_url_t url,
mu_url_t url,
mu_folder_t folder,
const char *name)
{
int (*m_init) (mu_mailbox_t) = NULL;
......@@ -127,10 +129,16 @@ _mailbox_create_from_record (mu_mailbox_t *pmbox,
}
mbox->url = url;
/* Create the folder before initializing the concrete mailbox.
The mailbox needs it's back pointer. */
status = mailbox_folder_create (mbox, name, record);
if (folder)
{
folder->ref++; /* FIXME: No ref/unref function for folders */
mbox->folder = folder;
}
else
/* Create the folder before initializing the concrete mailbox.
The mailbox needs it's back pointer. */
status = mailbox_folder_create (mbox, name, record);
if (status == 0)
status = m_init (mbox); /* Create the concrete mailbox type. */
......@@ -152,11 +160,12 @@ static int
_create_mailbox0 (mu_mailbox_t *pmbox, mu_url_t url, const char *name)
{
mu_record_t record = NULL;
if (mu_registrar_lookup_url (url, MU_FOLDER_ATTRIBUTE_FILE, &record, NULL)
== 0)
return _mailbox_create_from_record (pmbox, record, url, name);
return ENOSYS;
int rc;
rc = mu_registrar_lookup_url (url, MU_FOLDER_ATTRIBUTE_FILE, &record, NULL);
if (rc == 0)
rc = _mailbox_create_from_record (pmbox, record, url, NULL, name);
return rc;
}
static int
......@@ -203,7 +212,71 @@ mu_mailbox_create_from_record (mu_mailbox_t *pmbox, mu_record_t record,
rc = mu_url_create (&url, name);
if (rc)
return rc;
rc = _mailbox_create_from_record (pmbox, record, url, name);
rc = _mailbox_create_from_record (pmbox, record, url, NULL, name);
if (rc)
mu_url_destroy (&url);
return rc;
}
int
mu_mailbox_create_at (mu_mailbox_t *pmbox, mu_folder_t folder,
const char *name)
{
int rc;
mu_url_t url;
const char *oldpath;
rc = mu_url_dup (folder->url, &url);
if (rc)
return rc;
do
{
char *path;
size_t oldlen, len;
mu_record_t record;
rc = mu_url_sget_path (url, &oldpath);
if (rc)
break;
oldlen = strlen (oldpath);
if (oldlen == 0)
{
path = strdup (name);
if (!path)
{
rc = ENOMEM;
break;
}
}
else
{
if (oldpath[oldlen-1] == '/')
oldlen--;
len = oldlen + 1 + strlen (name) + 1;
path = malloc (len);
if (!path)
{
rc = ENOMEM;
break;
}
memcpy (path, oldpath, oldlen);
path[oldlen++] = '/';
strcpy (path + oldlen, name);
}
rc = mu_url_set_path (url, path);
free (path);
if (rc)
break;
rc = mu_registrar_lookup_url (url, MU_FOLDER_ATTRIBUTE_FILE,
&record, NULL);
if (rc)
break;
rc = _mailbox_create_from_record (pmbox, record, url, folder, name);
}
while (0);
if (rc)
mu_url_destroy (&url);
return rc;
......@@ -314,7 +387,24 @@ mu_mailbox_remove (mu_mailbox_t mbox)
if (mbox->flags & _MU_MAILBOX_REMOVED)
return MU_ERR_MBX_REMOVED;
if (!mbox->_remove)
return MU_ERR_EMPTY_VFN;
{
/* Try the owning folder delete method. See comment to mu_folder_delete
in folder.c. This may result in a recursive call to mu_mailbox_remove
which is blocked by setting the _MU_MAILBOX_REMOVED flag. */
int rc;
const char *path;
rc = mu_url_sget_path (mbox->url, &path);
if (rc == 0)
{
mbox->flags |= _MU_MAILBOX_REMOVED;
rc = mu_folder_delete (mbox->folder, path);
if (rc)
mbox->flags &= ~_MU_MAILBOX_REMOVED;
}
return rc;
}
return mbox->_remove (mbox);
}
......@@ -689,7 +779,7 @@ mu_mailbox_set_folder (mu_mailbox_t mbox, mu_folder_t folder)
{
if (mbox == NULL)
return EINVAL;
mbox->folder = folder;
mbox->folder = folder;
return 0;
}
......
......@@ -12,6 +12,7 @@ decode2047
encode2047
fltst
fsaf
fsfolder
imapio
listop
mailcap
......
......@@ -47,6 +47,7 @@ noinst_PROGRAMS = \
encode2047\
fltst\
fsaf\
fsfolder\
imapio\
listop\
mailcap\
......@@ -78,6 +79,9 @@ TESTSUITE_AT = \
encode2047.at\
fromflt.at\
fsaf.at\
fsfolder00.at\
fsfolder01.at\
fsfolder02.at\
hdrflt.at\
imapio.at\
inline-comment.at\
......
/* 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/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <mailutils/error.h>
#include <mailutils/errno.h>
#include <mailutils/folder.h>
#include <mailutils/stream.h>
#include <mailutils/stdstream.h>
#include <mailutils/list.h>
#include <mailutils/url.h>
#include <mailutils/util.h>
#include <mailutils/registrar.h>
#include <mailutils/sys/folder.h>
#include <mailutils/sys/registrar.h>
int sort_option;
int prefix_len;
struct command
{
char *verb;
int nargs;
char *args;
void (*handler) (mu_folder_t folder, char **argv);
};
static int
compare_response (void const *a, void const *b)
{
struct mu_list_response const *ra = a;
struct mu_list_response const *rb = b;
if (ra->level < rb->level)
return -1;
if (ra->level > rb->level)
return 1;
return strcmp (ra->name, rb->name);
}
static int
_print_list_entry (void *item, void *data)
{
struct mu_list_response *resp = item;
int len = data ? *(int*) data : 0;
mu_printf ("%c%c %c %4d %s\n",
(resp->type & MU_FOLDER_ATTRIBUTE_DIRECTORY) ? 'd' : '-',
(resp->type & MU_FOLDER_ATTRIBUTE_FILE) ? 'f' : '-',
resp->separator ? resp->separator : ' ',
resp->level,
resp->name + len);
return 0;
}
static void
com_list (mu_folder_t folder, char **argv)
{
int rc;
mu_list_t list;
mu_printf ("listing '%s' '%s'\n", argv[0], argv[1]);
rc = mu_folder_list (folder, argv[0], argv[1], 0, &list);
if (rc)
mu_diag_funcall (MU_DIAG_ERROR, "mu_folder_list", argv[0], rc);
else
{
if (sort_option)
mu_list_sort (list, compare_response);
mu_list_foreach (list, _print_list_entry, &prefix_len);
mu_list_destroy (&list);
}
}
static void
com_lsub (mu_folder_t folder, char **argv)
{
int rc;
mu_list_t list;
mu_printf ("listing subscriptions for '%s' '%s'\n", argv[0], argv[1]);
rc = mu_folder_lsub (folder, argv[0], argv[1], &list);
if (rc)
mu_diag_funcall (MU_DIAG_ERROR, "mu_folder_lsub", argv[0], rc);
else
{
if (sort_option)
mu_list_sort (list, compare_response);
mu_list_foreach (list, _print_list_entry, NULL);
mu_list_destroy (&list);
}
}
static void
com_rename (mu_folder_t folder, char **argv)
{
int rc;
mu_printf ("renaming %s to %s\n", argv[0], argv[1]);
rc = mu_folder_rename (folder, argv[0], argv[1]);
if (rc)
mu_diag_funcall (MU_DIAG_ERROR, "mu_folder_rename", argv[0], rc);
else
mu_printf ("rename successful\n");
}
static void
com_subscribe (mu_folder_t folder, char **argv)
{
int rc;
mu_printf ("subscribing %s\n", argv[0]);
rc = mu_folder_subscribe (folder, argv[0]);
if (rc)
mu_diag_funcall (MU_DIAG_ERROR, "mu_folder_subscribe", argv[0], rc);
else
mu_printf ("subscribe successful\n");
}
static void
com_unsubscribe (mu_folder_t folder, char **argv)
{
int rc;
mu_printf ("unsubscribing %s\n", argv[0]);
rc = mu_folder_unsubscribe (folder, argv[0]);
if (rc)
mu_diag_funcall (MU_DIAG_ERROR, "mu_folder_unsubscribe", argv[0], rc);
else
mu_printf ("unsubscribe successful\n");
}
static struct command comtab[] = {
{ "list", 2, "REF MBX", com_list },
{ "lsub", 2, "REF MBX", com_lsub },
{ "rename", 2, "OLD NEW", com_rename },
{ "subscribe", 1, "MBX", com_subscribe },
{ "unsubscribe", 1, "MBX", com_unsubscribe },
{ NULL }
};
static struct command *
find_command (const char *name)
{
struct command *cp;
for (cp = comtab; cp->verb; cp++)
if (strcmp (cp->verb, name) == 0)
return cp;
return NULL;
}
static void
usage ()
{
struct command *cp;
mu_printf (
"usage: %s [debug=SPEC] name=URL OP ARG [ARG...] [OP ARG [ARG...]...]\n",
mu_program_name);
mu_printf ("OPerations and corresponding ARGuments are:\n");
for (cp = comtab; cp->verb; cp++)
mu_printf (" %s %s\n", cp->verb, cp->args);
}
static int
_always_is_scheme (mu_record_t record, mu_url_t url, int flags)
{
return 1;
}
static struct _mu_record test_record =
{
0,
"file",
MU_RECORD_LOCAL,
MU_URL_SCHEME | MU_URL_PATH,
MU_URL_PATH,
mu_url_expand_path, /* URL init. */
NULL, /* Mailbox init. */
NULL, /* Mailer init. */
_mu_fsfolder_init, /* Folder init. */
NULL, /* No need for an back pointer. */
_always_is_scheme, /* _is_scheme method. */
NULL, /* _get_url method. */
NULL, /* _get_mailbox method. */
NULL, /* _get_mailer method. */
NULL /* _get_folder method. */
};
int
main (int argc, char **argv)
{
int i;
int rc;
mu_folder_t folder;
char *fname = NULL;
mu_set_program_name (argv[0]);
mu_registrar_record (&test_record);
if (argc == 1)
{
usage ();
exit (0);
}
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)
sort_option = 1;
else
break;
}
if (!fname)
{
mu_error ("name not specified");
exit (1);
}
if (fname[0] != '/')
{
char *cwd = mu_getcwd ();
prefix_len = strlen (cwd);
if (cwd[prefix_len-1] != '/')
prefix_len++;
fname = mu_make_file_name (cwd, fname);
free (cwd);
}
rc = mu_folder_create (&folder, fname);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_folder_create", fname, rc);
return 1;
}
rc = mu_folder_open (folder, MU_STREAM_READ);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_folder_open", fname, rc);
return 1;
}
while (i < argc)
{
char *comargs[2];
struct command *cmd;
cmd = find_command (argv[i]);
if (!cmd)
{
mu_error ("unknown command %s\n", argv[i]);
break;
}
i++;
if (i + cmd->nargs > argc)
{
mu_error ("not enough arguments for %s", cmd->verb);
break;
}
memcpy (comargs, argv + i, cmd->nargs * sizeof (comargs[0]));
i += cmd->nargs;
cmd->handler (folder, comargs);
}
mu_folder_close (folder);
mu_folder_destroy (&folder);
return 0;
}
# This file is part of GNU Mailutils. -*- Autotest -*-
# 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/>.
AT_SETUP([List])
AT_KEYWORDS([fsfolder folder-list])
AT_CHECK([
mkdir dir
> dir/foo
> dir/bar
> dir/foo.mbox
mkdir dir/subdir
> dir/subdir/file
> dir/subdir/baz.mbox
fsfolder name=dir sort dnl
list "" "*" dnl
list subdir "*" dnl
list "" "*.mbox" dnl
list "subdir" "*.mbox"
],
[0],
[listing '' '*'
d- / 0 dir/bar
d- / 0 dir/foo
d- / 0 dir/foo.mbox
d- / 0 dir/subdir
d- / 1 dir/subdir/baz.mbox
d- / 1 dir/subdir/file
listing 'subdir' '*'
d- / 0 dir/subdir/baz.mbox
d- / 0 dir/subdir/file
listing '' '*.mbox'
d- / 0 dir/foo.mbox
d- / 1 dir/subdir/baz.mbox
listing 'subdir' '*.mbox'
d- / 0 dir/subdir/baz.mbox
])
AT_CLEANUP
# This file is part of GNU Mailutils. -*- Autotest -*-
# 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/>.
AT_SETUP([Subscriptions])
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 "" "*"
],
[0],
[listing subscriptions for '' '*'
subscribing foo
subscribe successful
listing subscriptions for '' '*'
-f / 0 foo
subscribing baz
subscribe successful
subscribing foo/baz
subscribe successful
subscribing foo/bar
subscribe successful
listing subscriptions for '' '*'
-f / 0 baz
-f / 0 foo
-f / 0 foo/bar
-f / 0 foo/baz
listing subscriptions for 'foo' '*'
-f / 0 foo/bar
-f / 0 foo/baz
listing subscriptions for '' 'foo*'
-f / 0 foo
-f / 0 foo/bar
-f / 0 foo/baz
unsubscribing baz
unsubscribe successful
listing subscriptions for '' '*'
-f / 0 foo
-f / 0 foo/bar
-f / 0 foo/baz
unsubscribing foo
unsubscribe successful
listing subscriptions for '' '*'
-f / 0 foo/bar
-f / 0 foo/baz
])
AT_CLEANUP
# This file is part of GNU Mailutils. -*- Autotest -*-
# 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/>.
AT_SETUP([Rename])
AT_KEYWORDS([fsfolder folder-rename])
AT_CHECK([
mkdir dir
> dir/foo
fsfolder name=dir rename foo bar
fsfolder name=dir list "" "*"
> dir/baz
fsfolder name=dir rename bar baz
],
[0],
[renaming foo to bar
rename successful
listing '' '*'
d- / 0 dir/bar
renaming bar to baz
],
[fsfolder: mu_folder_rename(bar) failed: File exists
])
AT_CLEANUP
......@@ -68,6 +68,11 @@ m4_include([mailcap.at])
m4_include([wicket.at])
m4_include([prop.at])
AT_BANNER(File-system folder)
m4_include([fsfolder00.at])
m4_include([fsfolder01.at])
m4_include([fsfolder02.at])
AT_BANNER(Base64)
m4_include([base64e.at])
m4_include([base64d.at])
......
......@@ -133,7 +133,6 @@ static struct command comtab[] = {
{ "lsub", 2, "REF MBX", com_lsub },
{ "delete", 1, "MBX", com_delete },
{ "rename", 2, "OLD NEW", com_rename },
{ "delete", 1, "MBOX", com_delete },
{ "subscribe", 1, "MBX", com_subscribe },
{ "unsubscribe", 1, "MBX", com_unsubscribe },
{ NULL }
......
......@@ -37,12 +37,6 @@
#include <mailutils/sys/amd.h>
static int
_maildir_folder_init (mu_folder_t folder MU_ARG_UNUSED)
{
return 0;
}
static int
dir_exists (const char *name, const char *suf)
{
struct stat st;
......@@ -59,31 +53,42 @@ dir_exists (const char *name, const char *suf)
static int
_maildir_is_scheme (mu_record_t record, mu_url_t url, int flags)
{
if (mu_url_is_scheme (url, record->scheme))
return MU_FOLDER_ATTRIBUTE_FILE & flags;
if (mu_scheme_autodetect_p (url))
int scheme_matched = mu_url_is_scheme (url, record->scheme);
int rc = 0;
if (scheme_matched || mu_scheme_autodetect_p (url))
{
/* Attemp auto-detection */
const char *path;
struct stat st;
if (mu_url_sget_path (url, &path))
return 0;
if (stat (path, &st) < 0)
return 0;
{
if (errno == ENOENT && scheme_matched)
return MU_FOLDER_ATTRIBUTE_ALL & flags;
return 0;
}
if (!S_ISDIR (st.st_mode))
return 0;
if ((flags & MU_FOLDER_ATTRIBUTE_FILE)
&& dir_exists (path, TMPSUF)
&& dir_exists (path, CURSUF)
&& dir_exists (path, NEWSUF))
return MU_FOLDER_ATTRIBUTE_FILE|MU_FOLDER_ATTRIBUTE_DIRECTORY;
if (scheme_matched)
rc = MU_FOLDER_ATTRIBUTE_ALL;
else
{
rc |= MU_FOLDER_ATTRIBUTE_DIRECTORY;
if ((flags & MU_FOLDER_ATTRIBUTE_FILE)
&& dir_exists (path, TMPSUF)
&& dir_exists (path, CURSUF)
&& dir_exists (path, NEWSUF))
rc |= MU_FOLDER_ATTRIBUTE_FILE;
}
}
return 0;
return rc & flags;
}
static int
......@@ -106,7 +111,7 @@ static struct _mu_record _maildir_record =
mu_url_expand_path, /* Url init. */
_mailbox_maildir_init, /* Mailbox init. */
NULL, /* Mailer init. */
_maildir_folder_init, /* Folder init. */
_mu_fsfolder_init, /* Folder init. */
NULL, /* back pointer. */
_maildir_is_scheme, /* _is_scheme method. */
NULL, /* _get_url method. */
......
......@@ -37,12 +37,6 @@
#include <mailutils/util.h>
#include <mailutils/cctype.h>
static int
_mh_folder_init (mu_folder_t folder MU_ARG_UNUSED)
{
return 0;
}
/* Check if NAME is a valid MH message name */
static int
mh_message_name_p (const char *name)
......@@ -90,13 +84,11 @@ static int
_mh_is_scheme (mu_record_t record, mu_url_t url, int flags)
{
int rc = 0;
int scheme_matched = mu_url_is_scheme (url, record->scheme);
if (mu_url_is_scheme (url, record->scheme))
return MU_FOLDER_ATTRIBUTE_ALL & flags;
if (mu_scheme_autodetect_p (url))
if (scheme_matched || mu_scheme_autodetect_p (url))
{
/* Attemp auto-detection */
/* Attempt auto-detection */
const char *path;
struct stat st;
......@@ -104,18 +96,27 @@ _mh_is_scheme (mu_record_t record, mu_url_t url, int flags)
return 0;
if (stat (path, &st) < 0)
return 0; /* mu_mailbox_open will complain*/
{
if (errno == ENOENT && scheme_matched)
return MU_FOLDER_ATTRIBUTE_ALL & flags;
return 0; /* mu_mailbox_open will complain*/
}
if (!S_ISDIR (st.st_mode))
return 0;
rc |= (MU_FOLDER_ATTRIBUTE_DIRECTORY & flags);
if (scheme_matched)
rc = MU_FOLDER_ATTRIBUTE_ALL;
else
{
rc |= MU_FOLDER_ATTRIBUTE_DIRECTORY;
if ((flags & MU_FOLDER_ATTRIBUTE_FILE) && mh_dir_p (path))
return rc | MU_FOLDER_ATTRIBUTE_FILE;
if ((flags & MU_FOLDER_ATTRIBUTE_FILE) && mh_dir_p (path))
rc |= MU_FOLDER_ATTRIBUTE_FILE;
}
}
return 0;
return rc & flags;
}
static int
......@@ -142,7 +143,7 @@ static struct _mu_record _mh_record =
mu_url_expand_path, /* Url init. */
_mailbox_mh_init, /* Mailbox init. */
NULL, /* Mailer init. */
_mh_folder_init, /* Folder init. */
_mu_fsfolder_init, /* Folder init. */
NULL, /* back pointer. */
_mh_is_scheme, /* _is_scheme method. */
NULL, /* _get_url method. */
......
atconfig
atlocal
fldel
package.m4
testsuite
testsuite.dir
......
......@@ -50,6 +50,7 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
INCLUDES = @MU_LIB_COMMON_INCLUDES@
noinst_PROGRAMS = \
fldel\
lstuid\
mbdel\
mimetest\
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2010, 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/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <mailutils/mailutils.h>
int
main (int argc, char **argv)
{
int rc;
mu_folder_t f;
if (argc != 3)
{
fprintf (stderr, "usage: %s URL NAME\n", argv[0]);
return 1;
}
mu_register_all_mbox_formats ();
MU_ASSERT (mu_folder_create (&f, argv[1]));
rc = mu_folder_delete (f, argv[2]);
if (rc)
{
if (rc == ENOTEMPTY)
{
printf ("mailbox removed, but has subfolders\n");
rc = 0;
}
else
fprintf (stderr, "%s\n", mu_strerror (rc));
}
mu_folder_destroy (&f);
return rc != 0;
}