summaryrefslogtreecommitdiff
path: root/libmailbox
diff options
context:
space:
mode:
authorJeff Bailey <jbailey@gnu.org>1999-09-11 22:58:21 +0000
committerJeff Bailey <jbailey@gnu.org>1999-09-11 22:58:21 +0000
commit759a29ba3bff2db376a068f90f7e9ede5896a249 (patch)
treef8978993f6bad674bf0d042302010506022a2b53 /libmailbox
parentaaa222bbc4368755bc3e88fee1cf006613f7afe9 (diff)
downloadmailutils-759a29ba3bff2db376a068f90f7e9ede5896a249.tar.gz
mailutils-759a29ba3bff2db376a068f90f7e9ede5896a249.tar.bz2
Imported sourcesstartgnu
Diffstat (limited to 'libmailbox')
-rw-r--r--libmailbox/Makefile.am13
-rw-r--r--libmailbox/mailbox.c99
-rw-r--r--libmailbox/mailbox.h47
-rw-r--r--libmailbox/unixmbox.c268
-rw-r--r--libmailbox/unixmbox.h56
5 files changed, 483 insertions, 0 deletions
diff --git a/libmailbox/Makefile.am b/libmailbox/Makefile.am
new file mode 100644
index 000000000..1ad179b39
--- /dev/null
+++ b/libmailbox/Makefile.am
@@ -0,0 +1,13 @@
+# Use automake to process this file -*-Makefile-*-
+
+if INSTALL_MAILBOX
+include_HEADERS = mailbox.h
+lib_LTLIBRARIES = libmailbox.la
+else
+noinst_HEADERS = mailbox.h
+noinst_LTLIBRARIES = libmailbox.la
+endif
+
+libmailbox_la_SOURCES = mailbox.c unixmbox.c unixmbox.h
+libmailbox_la_LDFLAGS = -version-info 0:0:0
+
diff --git a/libmailbox/mailbox.c b/libmailbox/mailbox.c
new file mode 100644
index 000000000..51d894ee9
--- /dev/null
+++ b/libmailbox/mailbox.c
@@ -0,0 +1,99 @@
+/* copyright and license info go here */
+
+#include "mailbox.h"
+#include "unixmbox.h"
+
+#ifdef _HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+int _mbox_dummy1 (mailbox * mbox);
+int _mbox_dummy2 (mailbox * mbox, int num);
+int _mbox_dummy3 (mailbox * mbox, char *c);
+char *_mbox_dummy4 (mailbox * mbox, int num);
+
+mailbox *
+mbox_open (char *name)
+{
+ mailbox *mbox = malloc (sizeof (mailbox));
+ if (mbox == NULL)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ /* Set up with default data and dummy functions */
+ mbox->name = strdup (name);
+ if (mbox->name == NULL)
+ {
+ errno = ENOMEM;
+ free (mbox);
+ return NULL;
+ }
+ mbox->messages = 0;
+ mbox->num_deleted = 0;
+ mbox->sizes = NULL;
+ mbox->_data = NULL;
+ mbox->_close = _mbox_dummy1;
+ mbox->_delete = _mbox_dummy2;
+ mbox->_undelete = _mbox_dummy2;
+ mbox->_expunge = _mbox_dummy1;
+ mbox->_add_message = _mbox_dummy3;
+ mbox->_is_deleted = _mbox_dummy2;
+ mbox->_get_body = _mbox_dummy4;
+ mbox->_get_header = _mbox_dummy4;
+
+ if (unixmbox_open (mbox) == 0)
+ return mbox;
+ else
+ {
+ /*
+ * Check errno to find out why it failed, if it's simply not a
+ * unix mbox format message, then try other mailbox types,
+ * otherwise, leave errno set and return NULL
+ */
+ }
+
+ /* for example...
+ if (maildir_open (mbox, name) == 1)
+ return mbox;
+ else if (errno != 0)
+ return NULL;
+ else
+ errno = 0;
+ */
+
+ errno = ENOSYS;
+ return NULL;
+}
+
+/*
+ * Bogus functions for unimplemented functions that return int
+ */
+int
+_mbox_dummy1 (mailbox * mbox)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+_mbox_dummy2 (mailbox * mbox, int num)
+{
+ return _mbox_dummy1 (mbox);
+}
+int
+_mbox_dummy3 (mailbox * mbox, char *c)
+{
+ return _mbox_dummy1 (mbox);
+}
+
+/*
+ * Bogus function for unimplemented functions that return char *
+ */
+char *
+_mbox_dummy4 (mailbox * mbox, int num)
+{
+ errno = ENOSYS;
+ return NULL;
+}
diff --git a/libmailbox/mailbox.h b/libmailbox/mailbox.h
new file mode 100644
index 000000000..05b7e32ea
--- /dev/null
+++ b/libmailbox/mailbox.h
@@ -0,0 +1,47 @@
+/* copyright and license info go here */
+
+#ifndef _MAILBOX_H
+#define _MAILBOX_H 1
+
+#ifndef __P
+#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
+#define __P(args) args
+#else
+#define __P(args) ()
+#endif
+#endif /*!__P */
+
+/* These need to be documented */
+#define mbox_close(m) m->_close(m)
+#define mbox_delete(m,n) m->_delete(m,n)
+#define mbox_undelete(m,n) m->_undelete(m,n)
+#define mbox_expunge(m) m->_expunge(m)
+#define mbox_is_deleted(m,n) m->_is_deleted(m,n)
+#define mbox_add_message(m,s) m->_add_message(m,s)
+#define mbox_get_body(m,n) m->_get_body(m,n)
+#define mbox_get_header(m,n) m->_get_header(m,n)
+
+typedef struct _mailbox
+ {
+ /* Data */
+ char *name;
+ int messages;
+ int num_deleted;
+ int *sizes;
+ void *_data;
+
+ /* Functions */
+ int (*_close) __P ((struct _mailbox *));
+ int (*_delete) __P ((struct _mailbox *, int));
+ int (*_undelete) __P ((struct _mailbox *, int));
+ int (*_expunge) __P ((struct _mailbox *));
+ int (*_add_message) __P ((struct _mailbox *, char *));
+ int (*_is_deleted) __P ((struct _mailbox *, int));
+ char *(*_get_body) __P ((struct _mailbox *, int));
+ char *(*_get_header) __P ((struct _mailbox *, int));
+ }
+mailbox;
+
+mailbox *mbox_open __P ((char *name));
+
+#endif
diff --git a/libmailbox/unixmbox.c b/libmailbox/unixmbox.c
new file mode 100644
index 000000000..0e5e855d4
--- /dev/null
+++ b/libmailbox/unixmbox.c
@@ -0,0 +1,268 @@
+/* copyright and license info go here */
+
+#include "unixmbox.h"
+
+/*
+ * Opens and locks a mailbox
+ */
+int
+unixmbox_open (mailbox * mbox)
+{
+ char buf[80];
+ unsigned int max_count = 10;
+ int mess = 0;
+ unixmbox_data *data = malloc (sizeof (unixmbox_data));
+
+ if (data == NULL)
+ {
+ errno = ENOMEM;
+ free (data);
+ return -1;
+ }
+
+ mbox->_data = data;
+ data->file = fopen (mbox->name, "r+");
+ /* FIXME: do a good, NFS safe, file lock here, with error handling */
+ if (data->file == NULL)
+ {
+ /* errno is set by fopen() */
+ free (data);
+ return -1;
+ }
+
+ data->messages = malloc (sizeof (unixmbox_message) * max_count);
+ mbox->sizes = malloc (sizeof (int) * max_count);
+ if (data->messages == NULL || mbox->sizes == NULL)
+ {
+ unixmbox_close (mbox);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ while (fgets (buf, 80, data->file))
+ {
+ if (!strncmp (buf, "From ", 5))
+ {
+ /* Beginning of a header */
+ while (strchr (buf, '\n') == NULL)
+ fgets (buf, 80, data->file);
+
+ mbox->messages++;
+
+ if (mbox->messages > max_count)
+ {
+ max_count = mbox->messages * 2;
+ data->messages = realloc (data->messages,
+ max_count * sizeof (unixmbox_message));
+ mbox->sizes = realloc (mbox->sizes, max_count * sizeof (int));
+ if (data->messages == NULL || mbox->sizes == NULL)
+ {
+ unixmbox_close (mbox);
+ errno = ENOMEM;
+ return -1;
+ }
+ }
+
+ fgetpos (data->file, &(data->messages[mbox->messages - 1].header));
+ mbox->sizes[mbox->messages - 1] = 0;
+ data->messages[mbox->messages - 1].deleted = 0;
+ mess = 0;
+ }
+ else if (((!strncmp (buf, "\r\n", 2) || strlen (buf) <= 1)) && mess == 0)
+ {
+ /* Beginning of a body */
+ fgetpos (data->file, &(data->messages[mbox->messages - 1].body));
+ mbox->sizes[mbox->messages - 1] += strlen (buf) + 1;
+ mess = 1;
+ }
+ else
+ {
+ mbox->sizes[mbox->messages - 1] += strlen (buf) + 1;
+ fgetpos (data->file, &(data->messages[mbox->messages - 1].end));
+ }
+ }
+
+ mbox->_close = unixmbox_close;
+ mbox->_delete = unixmbox_delete;
+ mbox->_undelete = unixmbox_undelete;
+ mbox->_expunge = unixmbox_expunge;
+ mbox->_add_message = unixmbox_add_message;
+ mbox->_is_deleted = unixmbox_is_deleted;
+ mbox->_get_body = unixmbox_get_body;
+ mbox->_get_header = unixmbox_get_header;
+
+ return 0;
+}
+
+/*
+ * Closes and unlocks a mailbox, does not expunge
+ */
+int
+unixmbox_close (mailbox * mbox)
+{
+ unixmbox_data *data = mbox->_data;
+ /* FIXME: good file unlocking, to go along with the locking above */
+ fclose (data->file);
+ free (data->messages);
+ free (mbox->sizes);
+ free (data);
+ free (mbox);
+ return 0;
+}
+
+/*
+ * Marks a message for deletion
+ */
+int
+unixmbox_delete (mailbox * mbox, int num)
+{
+ unixmbox_data *data = mbox->_data;
+ if (num > mbox->messages || mbox_is_deleted (mbox, num))
+ {
+ errno = ERANGE;
+ return -1;
+ }
+ else
+ {
+ data->messages[num].deleted = 1;
+ mbox->num_deleted++;
+ }
+ return 0;
+}
+
+/*
+ * Unmark a message for deletion
+ */
+int
+unixmbox_undelete (mailbox * mbox, int num)
+{
+ unixmbox_data *data = mbox->_data;
+ if (num > mbox->messages || !mbox_is_deleted (mbox, num))
+ {
+ errno = ERANGE;
+ return -1;
+ }
+ else
+ {
+ data->messages[num].deleted = 0;
+ mbox->num_deleted--;
+ }
+ return 0;
+}
+
+/*
+ * Updates a mailbox to remove message marked for deletion
+ * FIXME: BROKEN! DOES NOT WORK! BLOWS UP REAL GOOD!
+ */
+int
+unixmbox_expunge (mailbox * mbox)
+{
+ unixmbox_data *data = mbox->_data;
+ int i = 0, size = 0;
+ char *buf;
+ fpos_t lastpos;
+
+ data->file = freopen (mbox->name, "r+", data->file);
+ if (data->file == NULL)
+ {
+ /* error handling */
+ }
+ fgetpos (data->file, &lastpos);
+
+ for (i = 0; i < mbox->messages; i++)
+ {
+ if (data->messages[i].deleted == 0)
+ {
+ fgetpos (data->file, &lastpos);
+ fsetpos (data->file, &(data->messages[i].header));
+ read (fileno (data->file), buf,
+ data->messages[i + 1].header - data->messages[i].header);
+ fprintf (data->file, "%s", buf);
+ size += strlen (buf);
+ free (buf);
+ }
+ }
+ ftruncate (fileno (data->file), size);
+ return 0;
+}
+
+/*
+ * Determines whether or a not a message is marked for deletion
+ */
+int
+unixmbox_is_deleted (mailbox * mbox, int num)
+{
+ unixmbox_data *data = mbox->_data;
+ return (data->messages[num].deleted == 1);
+}
+
+/*
+ * Adds a message to the mailbox
+ */
+int
+unixmbox_add_message (mailbox * mbox, char *message)
+{
+ /*
+ * FIXME: please write me
+ * move to end of file and write text, don't forget to update
+ * mbox->messages and mbox->_data->messages
+ */
+ errno = ENOSYS;
+ return -1;
+}
+
+/*
+ * Returns a message body
+ */
+char *
+unixmbox_get_body (mailbox * mbox, int num)
+{
+ unixmbox_data *data = mbox->_data;
+ int size = data->messages[num].end - data->messages[num].body;
+ char *buf = malloc ((1 + size) * sizeof (char));
+ if (buf == NULL)
+ {
+ errno = ENOMEM;
+ free (buf);
+ return NULL;
+ }
+ else if (num > mbox->messages || num < 0)
+ {
+ errno = ERANGE;
+ free (buf);
+ return NULL;
+ }
+
+ memset (buf, 0, size + 1);
+ fsetpos (data->file, &(data->messages[num].body));
+ fread (buf, size, sizeof (char), data->file);
+ return buf;
+}
+
+/*
+ * Returns just the header of a message
+ */
+char *
+unixmbox_get_header (mailbox * mbox, int num)
+{
+ unixmbox_data *data = mbox->_data;
+ int size = (data->messages[num].body - 1) - data->messages[num].header ;
+ char *buf = malloc ((1 + size) * sizeof (char));
+ if (buf == NULL)
+ {
+ errno = ENOMEM;
+ free (buf);
+ return NULL;
+ }
+ else if (num > mbox->messages || num < 0)
+ {
+ errno = ERANGE;
+ free (buf);
+ return NULL;
+ }
+
+ memset (buf, 0, size + 1);
+ fsetpos (data->file, &(data->messages[num].header));
+ fread (buf, size, sizeof (char), data->file);
+ return buf;
+}
diff --git a/libmailbox/unixmbox.h b/libmailbox/unixmbox.h
new file mode 100644
index 000000000..65d0784b1
--- /dev/null
+++ b/libmailbox/unixmbox.h
@@ -0,0 +1,56 @@
+/* copyright and license info go here */
+
+#ifndef _UNIXMBOX_H
+#define _UNIXMBOX_H 1
+#include <mailbox.h>
+#include "config.h"
+
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#elif HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+typedef struct _unixmbox_message
+ {
+ off_t header;
+ off_t body;
+ off_t end;
+ short deleted;
+ }
+unixmbox_message;
+
+typedef struct _unixmbox_data
+ {
+ unixmbox_message *messages;
+ FILE *file;
+ }
+unixmbox_data;
+
+int unixmbox_open (mailbox *mbox);
+int unixmbox_close (mailbox *mbox);
+int unixmbox_delete (mailbox *mbox, int num);
+int unixmbox_undelete (mailbox *mbox, int num);
+int unixmbox_expunge (mailbox *mbox);
+int unixmbox_is_deleted (mailbox *mbox, int num);
+int unixmbox_add_message (mailbox *mbox, char *message);
+char *unixmbox_get_body (mailbox *mbox, int num);
+char *unixmbox_get_header (mailbox *mbox, int num);
+
+#endif

Return to:

Send suggestions and report system problems to the System administrator.