summaryrefslogtreecommitdiff
path: root/libmailbox/unixmbox.c
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/unixmbox.c
parentaaa222bbc4368755bc3e88fee1cf006613f7afe9 (diff)
downloadmailutils-759a29ba3bff2db376a068f90f7e9ede5896a249.tar.gz
mailutils-759a29ba3bff2db376a068f90f7e9ede5896a249.tar.bz2
Imported sourcesstartgnu
Diffstat (limited to 'libmailbox/unixmbox.c')
-rw-r--r--libmailbox/unixmbox.c268
1 files changed, 268 insertions, 0 deletions
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;
+}

Return to:

Send suggestions and report system problems to the System administrator.