summaryrefslogtreecommitdiff
path: root/libmailutils/base
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-10-09 13:06:58 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-10-09 13:26:18 +0300
commitf3188dcc18d8de1192c87e7e0284800e9488b976 (patch)
treefed11275f4d8bbc28d8eb2239d93ddcba89fcb84 /libmailutils/base
parent37d7cd77d34cd4bf8d267b3010d923845fe74308 (diff)
downloadmailutils-f3188dcc18d8de1192c87e7e0284800e9488b976.tar.gz
mailutils-f3188dcc18d8de1192c87e7e0284800e9488b976.tar.bz2
Reorganize libmailutils directory structure.
* configure.ac (AC_CONFIG_FILES): Add libmailutils/ subdirs. * include/mailutils/Makefile.am: Update references to libmailutils. * po/POTFILES.in: Likewise. * libmailutils/.gitignore: Update. * libmailutils/Makefile.am: Use convenience libraries in subdirs. * libmailutils/string/Makefile.am: New file. * libmailutils/cstrcasecmp.c: Move to libmailutils/string. * libmailutils/cstrlower.c: Likewise. * libmailutils/cstrupper.c: Likewise. * libmailutils/strltrim.c: Likewise. * libmailutils/strskip.c: Likewise. * libmailutils/stripws.c: Likewise. * libmailutils/strrtrim.c: Likewise. * libmailutils/asnprintf.c: Likewise. * libmailutils/asprintf.c: Likewise. * libmailutils/muctype.c: Likewise. * libmailutils/vasnprintf.c: Likewise. * libmailutils/mkfilename.c: Likewise. * libmailutils/stream/Makefile.am: New file. * libmailutils/dbgstream.c: Move to libmailutils/stream. * libmailutils/file_stream.c: Likewise. * libmailutils/fltstream.c: Likewise. * libmailutils/iostream.c: Likewise. * libmailutils/mapfile_stream.c: Likewise. * libmailutils/memory_stream.c: Likewise. * libmailutils/message_stream.c: Likewise. * libmailutils/prog_stream.c: Likewise. * libmailutils/rdcache_stream.c: Likewise. * libmailutils/socket_stream.c: Likewise. * libmailutils/stdio_stream.c: Likewise. * libmailutils/stream.c: Likewise. * libmailutils/stream_printf.c: Likewise. * libmailutils/stream_vprintf.c: Likewise. * libmailutils/streamcpy.c: Likewise. * libmailutils/streamref.c: Likewise. * libmailutils/tcp.c: Likewise. * libmailutils/temp_file_stream.c: Likewise. * libmailutils/xscript-stream.c * libmailutils/cfg/Makefile.am: New file. * libmailutils/cfg/.gitignore: New file. * libmailutils/cfg_driver.c: Move to libmailutils/cfg/driver.c. * libmailutils/cfg_format.c: Move to libmailutils/cfg/format.c. * libmailutils/cfg_lexer.l: Move to libmailutils/cfg/lexer.l. * libmailutils/cfg_parser.y: Move to libmailutils/cfg/parser.y. * libmailutils/gocs.c: Move to libmailutils/cfg/gocs.c. * libmailutils/diag/Makefile.am: New file. * libmailutils/diag/.gitignore: New file. * libmailutils/debug.c: Move to libmailutils/diag. * libmailutils/diag.c: Likewise. * libmailutils/gdebug.c: Likewise. * libmailutils/errors: Likewise. * libmailutils/muerrno.cin: Likewise. * libmailutils/syslog.c: Likewise. * libmailutils/dbgstderr.c: Likewise. * libmailutils/dbgsyslog.c: Likewise. * libmailutils/address/Makefile.am: New file. * libmailutils/address.c: Move to libmailutils/address. * libmailutils/parse822.c: Likewise. * libmailutils/mailbox/Makefile.am: New file. * libmailutils/mailbox.c: Move to libmailutils/mailbox. * libmailutils/mbx_default.c: Likewise. * libmailutils/mbxitr.c: Likewise. * libmailutils/attribute.c: Likewise. * libmailutils/body.c: Likewise. * libmailutils/envelope.c: Likewise. * libmailutils/folder.c: Likewise. * libmailutils/hdritr.c: Likewise. * libmailutils/header.c: Likewise. * libmailutils/message.c: Likewise. * libmailutils/msgscan.c: Likewise. * libmailutils/mailer/Makefile.am: New file. * libmailutils/mailer.c: Move to libmailutils/mailer. * libmailutils/progmailer.c: Likewise. * libmailutils/mime/Makefile.am: New file. * libmailutils/attachment.c: Move to libmailutils/mime. * libmailutils/mime.c: Likewise. * libmailutils/mimehdr.c: Likewise. * libmailutils/server/Makefile.am: New file. * libmailutils/acl.c: Move to libmailutils/server. * libmailutils/server.c: Likewise. * libmailutils/msrv.c: Likewise. * libmailutils/ipsrv.c: Likewise. * libmailutils/auth/Makefile.am: New file. * libmailutils/auth.c: Move to libmailutils/auth. * libmailutils/mu_auth.c: Likewise. * libmailutils/system.c: Likewise. * libmailutils/base/Makefile.am: New file. * libmailutils/base/.gitignore: New file. * libmailutils/alloc.c: Move to libmailutils/base. * libmailutils/amd.c: Likewise. * libmailutils/argcv.c: Likewise. * libmailutils/assoc.c: Likewise. * libmailutils/daemon.c: Likewise. * libmailutils/date.c: Likewise. * libmailutils/fgetpwent.c: Likewise. * libmailutils/freeitem.c: Likewise. * libmailutils/getpass.c: Likewise. * libmailutils/iterator.c: Likewise. * libmailutils/kwd.c: Likewise. * libmailutils/list.c: Likewise. * libmailutils/listlist.c: Likewise. * libmailutils/locale.c: Likewise. * libmailutils/locker.c: Likewise. * libmailutils/mailcap.c: Likewise. * libmailutils/md5.c: Likewise. * libmailutils/monitor.c: Likewise. * libmailutils/munre.c: Likewise. * libmailutils/mutil.c: Likewise. * libmailutils/nls.c: Likewise. * libmailutils/nullrec.c: Likewise. * libmailutils/observer.c: Likewise. * libmailutils/opool.c: Likewise. * libmailutils/parsedate.y: Likewise. * libmailutils/permstr.c: Likewise. * libmailutils/property.c: Likewise. * libmailutils/registrar.c: Likewise. * libmailutils/refcount.c: Likewise. * libmailutils/rfc2047.c: Likewise. * libmailutils/sha1.c: Likewise. * libmailutils/secret.c: Likewise. * libmailutils/ticket.c: Likewise. * libmailutils/url.c: Likewise. * libmailutils/vartab.c: Likewise. * libmailutils/version.c: Likewise. * libmailutils/wicket.c: Likewise.
Diffstat (limited to 'libmailutils/base')
-rw-r--r--libmailutils/base/.gitignore1
-rw-r--r--libmailutils/base/Makefile.am80
-rw-r--r--libmailutils/base/alloc.c116
-rw-r--r--libmailutils/base/amd.c2033
-rw-r--r--libmailutils/base/argcv.c549
-rw-r--r--libmailutils/base/assoc.c529
-rw-r--r--libmailutils/base/daemon.c189
-rw-r--r--libmailutils/base/date.c245
-rw-r--r--libmailutils/base/fgetpwent.c163
-rw-r--r--libmailutils/base/freeitem.c29
-rw-r--r--libmailutils/base/getpass.c59
-rw-r--r--libmailutils/base/iterator.c284
-rw-r--r--libmailutils/base/kwd.c94
-rw-r--r--libmailutils/base/list.c693
-rw-r--r--libmailutils/base/listlist.c139
-rw-r--r--libmailutils/base/locale.c242
-rw-r--r--libmailutils/base/locker.c1027
-rw-r--r--libmailutils/base/mailcap.c740
-rw-r--r--libmailutils/base/md5.c454
-rw-r--r--libmailutils/base/monitor.c282
-rw-r--r--libmailutils/base/munre.c93
-rw-r--r--libmailutils/base/mutil.c1536
-rw-r--r--libmailutils/base/nls.c62
-rw-r--r--libmailutils/base/nullrec.c49
-rw-r--r--libmailutils/base/observer.c239
-rw-r--r--libmailutils/base/opool.c446
-rw-r--r--libmailutils/base/parsedate.y1206
-rw-r--r--libmailutils/base/permstr.c128
-rw-r--r--libmailutils/base/property.c192
-rw-r--r--libmailutils/base/refcount.c107
-rw-r--r--libmailutils/base/registrar.c443
-rw-r--r--libmailutils/base/rfc2047.c314
-rw-r--r--libmailutils/base/secret.c135
-rw-r--r--libmailutils/base/sha1.c418
-rw-r--r--libmailutils/base/ticket.c245
-rw-r--r--libmailutils/base/url.c1140
-rw-r--r--libmailutils/base/vartab.c346
-rw-r--r--libmailutils/base/version.c189
-rw-r--r--libmailutils/base/wicket.c357
39 files changed, 15593 insertions, 0 deletions
diff --git a/libmailutils/base/.gitignore b/libmailutils/base/.gitignore
new file mode 100644
index 000000000..e3e0cf0d2
--- /dev/null
+++ b/libmailutils/base/.gitignore
@@ -0,0 +1 @@
+parsedate.c
diff --git a/libmailutils/base/Makefile.am b/libmailutils/base/Makefile.am
new file mode 100644
index 000000000..4bb7acb47
--- /dev/null
+++ b/libmailutils/base/Makefile.am
@@ -0,0 +1,80 @@
+# GNU Mailutils -- a suite of utilities for electronic mail
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General
+# Public License along with this library. If not, see
+# <http://www.gnu.org/licenses/>.
+
+noinst_LTLIBRARIES = libbase.la
+
+libbase_la_SOURCES = \
+ alloc.c\
+ amd.c\
+ argcv.c\
+ assoc.c\
+ daemon.c\
+ date.c\
+ fgetpwent.c\
+ freeitem.c\
+ getpass.c\
+ iterator.c\
+ kwd.c\
+ list.c\
+ listlist.c\
+ locale.c\
+ locker.c\
+ mailcap.c\
+ md5.c\
+ monitor.c\
+ munre.c\
+ mutil.c\
+ nls.c\
+ nullrec.c\
+ observer.c\
+ opool.c\
+ parsedate.c\
+ permstr.c\
+ property.c\
+ registrar.c\
+ refcount.c\
+ rfc2047.c\
+ sha1.c\
+ secret.c\
+ ticket.c\
+ url.c\
+ vartab.c\
+ version.c\
+ wicket.c
+
+localedir = $(datadir)/locale
+AM_CPPFLAGS = \
+ -DSYSCONFDIR=\"$(sysconfdir)\"\
+ -DSITE_VIRTUAL_PWDDIR=\"@SITE_VIRTUAL_PWDDIR@\"\
+ -DLOCALEDIR=\"$(localedir)\"
+
+INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
+
+YLWRAP = $(SHELL) $(mu_aux_dir)/gylwrap
+AM_YFLAGS=-vt
+AM_LFLAGS=-dvp
+
+EXTRA_DIST = parsedate.y
+
+BUILT_SOURCES = parsedate.c
+
+parsedate.c: $(srcdir)/parsedate.y
+ $(YLWRAP) "$(YACC) $(AM_YFLAGS)" $< \
+ y.tab.c parsedate.c y.output parsedate.y.output \
+ -- -yy pd_yy
+
+
diff --git a/libmailutils/base/alloc.c b/libmailutils/base/alloc.c
new file mode 100644
index 000000000..05801bb1a
--- /dev/null
+++ b/libmailutils/base/alloc.c
@@ -0,0 +1,116 @@
+/* Error-proof memory allocation functions.
+ Copyright (C) 2008, 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This library 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mailutils/error.h>
+#include <mailutils/nls.h>
+#include <mailutils/alloc.h>
+
+void (*mu_alloc_die_hook) (void) = NULL;
+
+void
+mu_alloc_die ()
+{
+ if (mu_alloc_die_hook)
+ mu_alloc_die_hook ();
+ mu_error (_("Not enough memory"));
+ abort ();
+}
+
+void *
+mu_alloc (size_t size)
+{
+ void *p = malloc (size);
+ if (!p)
+ mu_alloc_die ();
+ return p;
+}
+
+void *
+mu_calloc (size_t nmemb, size_t size)
+{
+ void *p = calloc (nmemb, size);
+ if (!p)
+ mu_alloc_die ();
+ return p;
+}
+
+void *
+mu_zalloc (size_t size)
+{
+ void *p = mu_alloc (size);
+ memset (p, 0, size);
+ return p;
+}
+
+void *
+mu_realloc (void *p, size_t size)
+{
+ void *newp = realloc (p, size);
+ if (!newp)
+ mu_alloc_die ();
+ return newp;
+}
+
+char *
+mu_strdup (const char *s)
+{
+ char *news = strdup (s);
+ if (!news)
+ mu_alloc_die ();
+ return news;
+}
+
+/* Copied from gnulib */
+void *
+mu_2nrealloc (void *p, size_t *pn, size_t s)
+{
+ size_t n = *pn;
+
+ if (!p)
+ {
+ if (!n)
+ {
+ /* The approximate size to use for initial small allocation
+ requests, when the invoking code specifies an old size of
+ zero. 64 bytes is the largest "small" request for the
+ GNU C library malloc. */
+ enum { DEFAULT_MXFAST = 64 };
+
+ n = DEFAULT_MXFAST / s;
+ n += !n;
+ }
+ }
+ else
+ {
+ /* Set N = ceil (1.5 * N) so that progress is made if N == 1.
+ Check for overflow, so that N * S stays in size_t range.
+ The check is slightly conservative, but an exact check isn't
+ worth the trouble. */
+ if ((size_t) -1 / 3 * 2 / s <= n)
+ mu_alloc_die ();
+ n += (n + 1) / 2;
+ }
+
+ *pn = n;
+ return mu_realloc (p, n * s);
+}
+
diff --git a/libmailutils/base/amd.c b/libmailutils/base/amd.c
new file mode 100644
index 000000000..a5dac3f05
--- /dev/null
+++ b/libmailutils/base/amd.c
@@ -0,0 +1,2033 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library; if not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301 USA */
+
+/* Mailutils Abstract Mail Directory Layer
+ First draft by Sergey Poznyakoff.
+ Thanks Tang Yong Ping <yongping.tang@radixs.com> for initial
+ patch (although not used here).
+
+ This module provides basic support for "MH" and "Maildir" formats. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <dirent.h>
+
+#ifdef WITH_PTHREAD
+# ifdef HAVE_PTHREAD_H
+# ifndef _XOPEN_SOURCE
+# define _XOPEN_SOURCE 500
+# endif
+# include <pthread.h>
+# endif
+#endif
+
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/cctype.h>
+#include <mailutils/cstr.h>
+#include <mailutils/attribute.h>
+#include <mailutils/body.h>
+#include <mailutils/debug.h>
+#include <mailutils/envelope.h>
+#include <mailutils/error.h>
+#include <mailutils/errno.h>
+#include <mailutils/header.h>
+#include <mailutils/locker.h>
+#include <mailutils/message.h>
+#include <mailutils/mutil.h>
+#include <mailutils/property.h>
+#include <mailutils/stream.h>
+#include <mailutils/url.h>
+#include <mailutils/observer.h>
+#include <mailutils/sys/stream.h>
+#include <mailutils/sys/mailbox.h>
+#include <mailutils/sys/registrar.h>
+#include <mailutils/sys/url.h>
+#include <mailutils/sys/amd.h>
+
+static void amd_destroy (mu_mailbox_t mailbox);
+static int amd_open (mu_mailbox_t, int);
+static int amd_close (mu_mailbox_t);
+static int amd_get_message (mu_mailbox_t, size_t, mu_message_t *);
+static int amd_quick_get_message (mu_mailbox_t mailbox, mu_message_qid_t qid,
+ mu_message_t *pmsg);
+static int amd_append_message (mu_mailbox_t, mu_message_t);
+static int amd_messages_count (mu_mailbox_t, size_t *);
+static int amd_messages_recent (mu_mailbox_t, size_t *);
+static int amd_message_unseen (mu_mailbox_t, size_t *);
+static int amd_expunge (mu_mailbox_t);
+static int amd_sync (mu_mailbox_t);
+static int amd_uidnext (mu_mailbox_t mailbox, size_t *puidnext);
+static int amd_uidvalidity (mu_mailbox_t, unsigned long *);
+static int amd_scan (mu_mailbox_t, size_t, size_t *);
+static int amd_is_updated (mu_mailbox_t);
+static int amd_get_size (mu_mailbox_t, mu_off_t *);
+
+static int amd_body_size (mu_body_t body, size_t *psize);
+static int amd_body_lines (mu_body_t body, size_t *plines);
+
+static int amd_header_fill (void *data, char **pbuf, size_t *plen);
+
+static int amd_get_attr_flags (mu_attribute_t attr, int *pflags);
+static int amd_set_attr_flags (mu_attribute_t attr, int flags);
+static int amd_unset_attr_flags (mu_attribute_t attr, int flags);
+
+static void _amd_message_delete (struct _amd_data *amd,
+ struct _amd_message *msg);
+static int amd_pool_open (struct _amd_message *mhm);
+static int amd_pool_open_count (struct _amd_data *amd);
+static void amd_pool_flush (struct _amd_data *amd);
+static struct _amd_message **amd_pool_lookup (struct _amd_message *mhm);
+
+static int amd_envelope_date (mu_envelope_t envelope, char *buf, size_t len,
+ size_t *psize);
+static int amd_envelope_sender (mu_envelope_t envelope, char *buf, size_t len,
+ size_t *psize);
+static int amd_remove_mbox (mu_mailbox_t mailbox);
+
+
+static int amd_body_stream_read (mu_stream_t str, char *buffer,
+ size_t buflen,
+ size_t *pnread);
+static int amd_body_stream_readdelim (mu_stream_t is,
+ char *buffer, size_t buflen,
+ int delim,
+ size_t *pnread);
+static int amd_body_stream_size (mu_stream_t str, mu_off_t *psize);
+static int amd_body_stream_seek (mu_stream_t str, mu_off_t off,
+ mu_off_t *presult);
+
+struct _amd_body_stream
+{
+ struct _mu_stream stream;
+ mu_body_t body;
+ mu_off_t off;
+};
+
+
+/* Operations on message array */
+
+/* Perform binary search for message MSG on a segment of message array
+ of AMD between the indexes FIRST and LAST inclusively.
+ If found, return 0 and store index of the located entry in the
+ variable PRET. Otherwise, return 1 and place into PRET index of
+ the nearest array element that is less than MSG (in the sense of
+ amd->msg_cmp)
+ Indexes are zero-based. */
+
+static int
+amd_msg_bsearch (struct _amd_data *amd, mu_off_t first, mu_off_t last,
+ struct _amd_message *msg,
+ mu_off_t *pret)
+{
+ mu_off_t mid;
+ int rc;
+
+ if (last < first)
+ return 1;
+
+ mid = (first + last) / 2;
+ rc = amd->msg_cmp (amd->msg_array[mid], msg);
+ if (rc > 0)
+ return amd_msg_bsearch (amd, first, mid-1, msg, pret);
+ *pret = mid;
+ if (rc < 0)
+ return amd_msg_bsearch (amd, mid+1, last, msg, pret);
+ /* else */
+ return 0;
+}
+
+/* Search for message MSG in the message array of AMD.
+ If found, return 0 and store index of the located entry in the
+ variable PRET. Otherwise, return 1 and place into PRET index of
+ the array element that is less than MSG (in the sense of
+ amd->msg_cmp)
+ Index returned in PRET is 1-based, so *PRET == 0 means that MSG
+ is less than the very first element of the message array.
+
+ In other words, when amd_msg_lookup() returns 1, the value in *PRET
+ can be regarded as a 0-based index of the array slot where MSG can
+ be inserted */
+
+int
+amd_msg_lookup (struct _amd_data *amd, struct _amd_message *msg,
+ size_t *pret)
+{
+ int rc;
+ mu_off_t i;
+
+ if (amd->msg_count == 0)
+ {
+ *pret = 0;
+ return 1;
+ }
+
+ rc = amd->msg_cmp (msg, amd->msg_array[0]);
+ if (rc < 0)
+ {
+ *pret = 0;
+ return 1;
+ }
+ else if (rc == 0)
+ {
+ *pret = 1;
+ return 0;
+ }
+
+ rc = amd->msg_cmp (msg, amd->msg_array[amd->msg_count - 1]);
+ if (rc > 0)
+ {
+ *pret = amd->msg_count;
+ return 1;
+ }
+ else if (rc == 0)
+ {
+ *pret = amd->msg_count;
+ return 0;
+ }
+
+ rc = amd_msg_bsearch (amd, 0, amd->msg_count - 1, msg, &i);
+ *pret = i + 1;
+ return rc;
+}
+
+#define AMD_MSG_INC 64
+
+/* Prepare the message array for insertion of a new message
+ at position INDEX (zero based), by moving its contents
+ one slot to the right. If necessary, expand the array by
+ AMD_MSG_INC */
+int
+amd_array_expand (struct _amd_data *amd, size_t index)
+{
+ if (amd->msg_count == amd->msg_max)
+ {
+ struct _amd_message **p;
+
+ amd->msg_max += AMD_MSG_INC; /* FIXME: configurable? */
+ p = realloc (amd->msg_array, amd->msg_max * amd->msg_size);
+ if (!p)
+ {
+ amd->msg_max -= AMD_MSG_INC;
+ return ENOMEM;
+ }
+ amd->msg_array = p;
+ }
+ memmove (&amd->msg_array[index+1], &amd->msg_array[index],
+ (amd->msg_count-index) * amd->msg_size);
+ amd->msg_count++;
+ return 0;
+}
+
+/* Shrink the message array by removing element at INDEX-1 and
+ shifting left by one position all the elements on the right of
+ it. */
+int
+amd_array_shrink (struct _amd_data *amd, size_t index)
+{
+ memmove (&amd->msg_array[index-1], &amd->msg_array[index],
+ (amd->msg_count-index) * amd->msg_size);
+ amd->msg_count--;
+ return 0;
+}
+
+
+int
+amd_init_mailbox (mu_mailbox_t mailbox, size_t amd_size,
+ struct _amd_data **pamd)
+{
+ int status;
+ struct _amd_data *amd;
+
+ if (mailbox == NULL)
+ return MU_ERR_MBX_NULL;
+ if (amd_size < sizeof (*amd))
+ return EINVAL;
+
+ amd = mailbox->data = calloc (1, amd_size);
+ if (mailbox->data == NULL)
+ return ENOMEM;
+
+ /* Back pointer. */
+ amd->mailbox = mailbox;
+
+ status = mu_url_aget_path (mailbox->url, &amd->name);
+ if (status)
+ {
+ free (amd);
+ mailbox->data = NULL;
+ return status;
+ }
+
+ /* Overloading the defaults. */
+ mailbox->_destroy = amd_destroy;
+
+ mailbox->_open = amd_open;
+ mailbox->_close = amd_close;
+
+ /* Overloading of the entire mailbox object methods. */
+ mailbox->_get_message = amd_get_message;
+ mailbox->_quick_get_message = amd_quick_get_message;
+ mailbox->_append_message = amd_append_message;
+ mailbox->_messages_count = amd_messages_count;
+ mailbox->_messages_recent = amd_messages_recent;
+ mailbox->_message_unseen = amd_message_unseen;
+ mailbox->_expunge = amd_expunge;
+ mailbox->_sync = amd_sync;
+ mailbox->_uidvalidity = amd_uidvalidity;
+ mailbox->_uidnext = amd_uidnext;
+
+ mailbox->_scan = amd_scan;
+ mailbox->_is_updated = amd_is_updated;
+
+ mailbox->_get_size = amd_get_size;
+ mailbox->_remove = amd_remove_mbox;
+
+ MU_DEBUG1 (mailbox->debug, MU_DEBUG_TRACE1, "amd_init(%s)\n", amd->name);
+ *pamd = amd;
+ return 0;
+}
+
+static void
+amd_destroy (mu_mailbox_t mailbox)
+{
+ struct _amd_data *amd = mailbox->data;
+ size_t i;
+
+ if (!amd)
+ return;
+
+ amd_pool_flush (amd);
+ mu_monitor_wrlock (mailbox->monitor);
+ for (i = 0; i < amd->msg_count; i++)
+ {
+ mu_message_destroy (&amd->msg_array[i]->message, amd->msg_array[i]);
+ free (amd->msg_array[i]);
+ }
+ free (amd->msg_array);
+
+ if (amd->name)
+ free (amd->name);
+
+ free (amd);
+ mailbox->data = NULL;
+ mu_monitor_unlock (mailbox->monitor);
+}
+
+static int
+amd_open (mu_mailbox_t mailbox, int flags)
+{
+ struct _amd_data *amd = mailbox->data;
+ struct stat st;
+
+ mailbox->flags = flags;
+ if (stat (amd->name, &st) < 0)
+ {
+ if ((flags & MU_STREAM_CREAT) && errno == ENOENT)
+ {
+ int rc;
+ int perms = mu_stream_flags_to_mode (flags, 1);
+ if (mkdir (amd->name, S_IRUSR|S_IWUSR|S_IXUSR|perms))
+ return errno;
+ if (stat (amd->name, &st) < 0)
+ return errno;
+ if (amd->create && (rc = amd->create (amd, flags)))
+ return rc;
+ }
+ else
+ return errno;
+ }
+
+ if (!S_ISDIR (st.st_mode))
+ return EINVAL;
+
+ if (mailbox->locker == NULL)
+ mu_locker_create (&mailbox->locker, "/dev/null", 0);
+
+ return 0;
+}
+
+static int
+amd_close (mu_mailbox_t mailbox)
+{
+ struct _amd_data *amd;
+ int i;
+
+ if (!mailbox)
+ return MU_ERR_MBX_NULL;
+
+ amd = mailbox->data;
+
+ /* Destroy all cached data */
+ amd_pool_flush (amd);
+ mu_monitor_wrlock (mailbox->monitor);
+ for (i = 0; i < amd->msg_count; i++)
+ {
+ mu_message_destroy (&amd->msg_array[i]->message, amd->msg_array[i]);
+ free (amd->msg_array[i]);
+ }
+ free (amd->msg_array);
+ amd->msg_array = NULL;
+
+ amd->msg_count = 0; /* number of messages in the list */
+ amd->msg_max = 0; /* maximum message buffer capacity */
+
+ amd->uidvalidity = 0;
+ mu_monitor_unlock (mailbox->monitor);
+
+ return 0;
+}
+
+static int
+amd_message_qid (mu_message_t msg, mu_message_qid_t *pqid)
+{
+ struct _amd_message *mhm = mu_message_get_owner (msg);
+
+ return mhm->amd->cur_msg_file_name (mhm, pqid);
+}
+
+struct _amd_message *
+_amd_get_message (struct _amd_data *amd, size_t msgno)
+{
+ msgno--;
+ if (msgno >= amd->msg_count)
+ return NULL;
+ return amd->msg_array[msgno];
+}
+
+static int
+_amd_attach_message (mu_mailbox_t mailbox, struct _amd_message *mhm,
+ mu_message_t *pmsg)
+{
+ int status;
+ mu_message_t msg;
+
+ /* Check if we already have it. */
+ if (mhm->message)
+ {
+ if (pmsg)
+ *pmsg = mhm->message;
+ return 0;
+ }
+
+ /* Get an empty message struct. */
+ status = mu_message_create (&msg, mhm);
+ if (status != 0)
+ return status;
+
+ /* Set the header. */
+ {
+ mu_header_t header = NULL;
+ status = mu_header_create (&header, NULL, 0);
+ if (status != 0)
+ {
+ mu_message_destroy (&msg, mhm);
+ return status;
+ }
+ mu_header_set_fill (header, amd_header_fill, msg);
+ /*FIXME:
+ mu_header_set_get_fvalue (header, amd_header_get_fvalue, msg);
+ */
+ mu_message_set_header (msg, header, mhm);
+ }
+
+ /* Set the attribute. */
+ {
+ mu_attribute_t attribute;
+ status = mu_attribute_create (&attribute, msg);
+ if (status != 0)
+ {
+ mu_message_destroy (&msg, mhm);
+ return status;
+ }
+ mu_attribute_set_get_flags (attribute, amd_get_attr_flags, msg);
+ mu_attribute_set_set_flags (attribute, amd_set_attr_flags, msg);
+ mu_attribute_set_unset_flags (attribute, amd_unset_attr_flags, msg);
+ mu_message_set_attribute (msg, attribute, mhm);
+ }
+
+ /* Prepare the body. */
+ {
+ mu_body_t body = NULL;
+ struct _amd_body_stream *str;
+
+ if ((status = mu_body_create (&body, msg)) != 0)
+ return status;
+
+ str = (struct _amd_body_stream *)
+ _mu_stream_create (sizeof (*str),
+ mailbox->flags | MU_STREAM_SEEK |
+ _MU_STR_OPEN);
+ if (!str)
+ {
+ mu_body_destroy (&body, msg);
+ mu_message_destroy (&msg, mhm);
+ return ENOMEM;
+ }
+ str->stream.read = amd_body_stream_read;
+ str->stream.readdelim = amd_body_stream_readdelim;
+ str->stream.size = amd_body_stream_size;
+ str->stream.seek = amd_body_stream_seek;
+ mu_body_set_stream (body, (mu_stream_t) str, msg);
+ mu_body_clear_modified (body);
+ mu_body_set_size (body, amd_body_size, msg);
+ mu_body_set_lines (body, amd_body_lines, msg);
+ mu_message_set_body (msg, body, mhm);
+ str->body = body;
+ }
+
+ /* Set the envelope. */
+ {
+ mu_envelope_t envelope = NULL;
+ status = mu_envelope_create (&envelope, msg);
+ if (status != 0)
+ {
+ mu_message_destroy (&msg, mhm);
+ return status;
+ }
+ mu_envelope_set_sender (envelope, amd_envelope_sender, msg);
+ mu_envelope_set_date (envelope, amd_envelope_date, msg);
+ mu_message_set_envelope (msg, envelope, mhm);
+ }
+
+ /* Set the UID. */
+ if (mhm->amd->message_uid)
+ mu_message_set_uid (msg, mhm->amd->message_uid, mhm);
+ mu_message_set_qid (msg, amd_message_qid, mhm);
+
+ /* Attach the message to the mailbox mbox data. */
+ mhm->