diff options
author | Jakob Kaivo <jkaivo@ndn.net> | 1999-11-24 02:10:35 +0000 |
---|---|---|
committer | Jakob Kaivo <jkaivo@ndn.net> | 1999-11-24 02:10:35 +0000 |
commit | 5f3d0446aa5694c64d925623e2d81d5098ec3341 (patch) | |
tree | 6299fd3ab3514fdfe48600155fbb1dfc1e939fd6 | |
parent | 6c15b6c306318bccd2056c1c5965604cc04df6ea (diff) | |
download | mailutils-5f3d0446aa5694c64d925623e2d81d5098ec3341.tar.gz mailutils-5f3d0446aa5694c64d925623e2d81d5098ec3341.tar.bz2 |
Added beginnings of Maildir support.
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | libmailbox/maildir.c | 397 | ||||
-rw-r--r-- | libmailbox/maildir.h | 91 |
4 files changed, 502 insertions, 0 deletions
@@ -1,3 +1,15 @@ +1999-11-23 Jakob 'sparky' Kaivo <jkaivo@elijah.nodomainname.net> + + * TODO: Mention Maildir + + * libmailbox/mailbox.c (mbox_init): new function + + * libmailbox/maildir.h: new file + + * libmailbox/maildir.c: new file + + * libmailbox/mailbox.c (mbox_open): uncommented maildir_open attempt + 1999-11-15 Jeff Bailey <jbailey@nisa.net> * lib/ansi2knr*: Add @@ -20,6 +20,8 @@ + libmailbox has a nasty bug -- if the mailbox is empty, the library has no idea what to do (Shaleh Oct 07/99) + +* Maildir is VERY rough [mail] - clean up 'mail''s compilation, why is there a mail script? diff --git a/libmailbox/maildir.c b/libmailbox/maildir.c new file mode 100644 index 000000000..bfbca822b --- /dev/null +++ b/libmailbox/maildir.c @@ -0,0 +1,397 @@ +/* GNU mailutils - a suite of utilities for electronic mail + Copyright (C) 1999 Free Software Foundation, Inc. + + This program 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 2, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "maildir.h" + +/* + * Opens a mailbox + */ +int +maildir_open (mailbox * mbox) +{ + int i; + int alloced = 0; + maildir_data *data; + struct dirent *entry; + char old_dir[PATH_MAX]; + struct utsname *utsinfo; + uname (utsinfo); + + getcwd (old_dir, PATH_MAX); + chdir (mbox->name); + + data->new = opendir ("new"); + data->tmp = opendir ("tmp"); + data->cur = opendir ("cur"); + data->time = time (NULL); + data->pid = getpid (); + data->sequence = 0; + /* data->host = strdup (utsinfo->sysname); */ + data->messages = malloc (10 * sizeof (maildir_message)); + alloced = 10; + + /* process the new directory */ + while ((entry = readdir (data->new)) && (entry != NULL)) + { + /* no dot files */ + if (entry->d_name[0] != '.') + { + if (mbox->messages >= alloced) + { + alloced *= 2; + data->messages = realloc (data->messages, + alloced * sizeof (maildir_message)); + /* check */ + } + data->messages[mbox->messages].deleted = 0; + data->messages[mbox->messages].info = NULL; + data->messages[mbox->messages].location = new; + data->messages[mbox->messages].file = strdup (entry->d_name); + /* check */ + mbox->messages++; + } + } + + /* then the cur directory */ + while ((entry = readdir (data->cur)) && (entry != NULL)) + { + if (entry->d_name[0] != '.') + { + if (mbox->messages >= alloced) + { + alloced *= 2; + data->messages = realloc (data->messages, + alloced * sizeof (maildir_message)); + /* check */ + } + data->messages[mbox->messages].deleted = 0; + data->messages[mbox->messages].location = cur; + data->messages[mbox->messages].file = strdup (entry->d_name); + /* check */ + /* data->messages[i].info = parse_for_info (entry->d_name); */ + mbox->messages++; + } + } + + for (i=0; i < mbox->messages; i++) + { + FILE *f; + char buf[80]; + chdir (mbox->name); + if (data->messages[i].location == new) + chdir ("new"); + else if (data->messages[i].location == cur) + chdir ("cur"); + f = fopen (data->messages[i].file, "r"); + data->messages[i].body = 0; + while (fgets (buf, 80, f)) + if (!strncmp (buf, "\r\n", 2) || strlen (buf) <= 1) + fgetpos (f, &(data->messages[i].body)); + fclose (f); + } + + mbox->_data = data; + mbox->_close = maildir_close; + mbox->_delete = maildir_delete; + mbox->_undelete = maildir_undelete; + mbox->_expunge = maildir_expunge; + mbox->_add_message = maildir_add_message; + mbox->_is_deleted = maildir_is_deleted; + mbox->_lock = maildir_lock; + mbox->_get_body = maildir_get_body; + mbox->_get_header = maildir_get_header; + + chdir (old_dir); + return 0; +} + +/* + * Closes and unlocks a mailbox, does not expunge + */ +int +maildir_close (mailbox * mbox) +{ + /* FIXME: hack from unixmbox */ + return 0; +} + +/* + * Marks a message for deletion + */ +int +maildir_delete (mailbox * mbox, unsigned int num) +{ + maildir_data *data; + + if (mbox == NULL) + { + errno = EINVAL; + return -1; + } + + if (num > mbox->messages || mbox_is_deleted (mbox, num)) + { + errno = ERANGE; + return -1; + } + + data = mbox->_data; + data->messages[num].deleted = 1; + mbox->num_deleted++; + + return 0; +} + +/* + * Unmark a message for deletion + */ +int +maildir_undelete (mailbox * mbox, unsigned int num) +{ + maildir_data *data; + + if (mbox == NULL) + { + errno = EINVAL; + return -1; + } + + if (num > mbox->messages || !mbox_is_deleted (mbox, num)) + { + errno = ERANGE; + return -1; + } + + data = mbox->_data; + data->messages[num].deleted = 0; + mbox->num_deleted--; + + return 0; +} + +/* + * Updates a mailbox to remove message marked for deletion + */ +int +maildir_expunge (mailbox * mbox) +{ + maildir_data *data; + int i = 0; + char old_dir[PATH_MAX]; + + if (mbox == NULL) + { + errno = EINVAL; + return -1; + } + + getcwd (old_dir, PATH_MAX); + chdir (mbox->name); + + if (mbox->num_deleted) + { + data = mbox->_data; + + for (i = 0; i < mbox->messages; i++) + { + if (data->messages[i].deleted == 0) + { + unlink (data->messages[i].file); + mbox->num_deleted--; + } + } + } + /* reorder messages? */ + + chdir (old_dir); + return 0; +} + +/* + * Determines whether or a not a message is marked for deletion + */ +int +maildir_is_deleted (mailbox * mbox, unsigned int num) +{ + maildir_data *data; + + if (mbox == NULL) + { + errno = EINVAL; + return -1; + } + if (mbox->num_deleted == 0) + return 0; + data = mbox->_data; + return (data->messages[num].deleted == 1); +} + +int +maildir_is_updated (mailbox *mbox) +{ + struct stat st; + maildir_data *data; + + if (mbox == NULL) + { + errno = EINVAL; + return -1; + } + if (stat (mbox->name, &st) == -1) + return -1; + data = mbox->_data; + return (st.st_mtime > data->last_mod_time); +} + +/* + * Adds a message to the mailbox + */ +int +maildir_add_message (mailbox * mbox, char *message) +{ + /* + * FIXME: please write me + * http://www.qmail.org/man/man5/maildir.html + */ + errno = ENOSYS; + return -1; +} + +/* + * Returns a message body + */ +char * +maildir_get_body (mailbox * mbox, unsigned int num) +{ + maildir_data *data; + char *buf; + char old_dir[PATH_MAX]; + FILE *f; + struct stat st; + size_t size; + + if (mbox == NULL) + { + errno = EINVAL; + return NULL; + } + if (num > mbox->messages || num < 0) + { + errno = ERANGE; + return NULL; + } + + data = mbox->_data; + getcwd (old_dir, PATH_MAX); + chdir (mbox->name); + + if (data->messages[num].location == cur) + chdir ("cur"); + else if (data->messages[num].location == tmp) + chdir ("tmp"); + else if (data->messages[num].location == new) + chdir ("new"); + + f = fopen (data->messages[num].file, "r"); + if (f == NULL) + { + chdir (old_dir); + perror (NULL); + return NULL; + } + + stat (data->messages[num].file, &st); + size = st.st_size - data->messages[num].body + 1; + + buf = malloc (sizeof (char) * size); + if (buf == NULL) + { + fclose (f); + chdir (old_dir); + errno = ENOMEM; + return NULL; + } + + memset (buf, 0, size); + if (fsetpos (f, &(data->messages[num].body)) == -1) + { + fclose (f); + chdir (old_dir); + free (buf); + return NULL; + } + + if (fread (buf, sizeof (char), size-1, f) < size) + { + fclose (f); + chdir (old_dir); + free (buf); + return NULL; + } + + fclose (f); + chdir (old_dir); + return buf; +} + +/* + * Returns just the header of a message + */ +char * +maildir_get_header (mailbox * mbox, unsigned int num) +{ + maildir_data *data; + char *buf; + + if ( mbox == NULL ) + { + errno = EINVAL; + return NULL; + } + + if (num > mbox->messages) + { + errno = ERANGE; + return NULL; + } + + data = mbox->_data; + buf = NULL; /* FIXME: read the file until data->message[num].body */ + return buf; +} + +/* + * Sets lock mode for a mailbox + * FIXME: What to do for Maildir? no locking? + */ +int +maildir_lock (mailbox *mbox, mailbox_lock_t mode) +{ + return 0; +} + +/* FIXME: not implemented */ +int +maildir_scan (mailbox *mbox) +{ + errno = ENOSYS; + return -1; +} diff --git a/libmailbox/maildir.h b/libmailbox/maildir.h new file mode 100644 index 000000000..b9c94682d --- /dev/null +++ b/libmailbox/maildir.h @@ -0,0 +1,91 @@ +/* GNU mailutils - a suite of utilities for electronic mail + Copyright (C) 1999 Free Software Foundation, Inc. + + This program 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 2, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _MAILDIR_H +#define _MAILDIR_H 1 +#include <mailbox.h> +#include "config.h" + +#ifdef HAVE_STDIO_H +#include <stdio.h> +#endif + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +/* FIXME need auto* wrapper */ +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> +#include <sys/utsname.h> +#include <time.h> + +#include <fcntl.h> + +#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 _maildir_message + { + off_t body; + char deleted; + enum { new, tmp, cur } location; + char *file; + char *info; + } +maildir_message; + +typedef struct _maildir_data + { + maildir_message *messages; + DIR *new; + DIR *cur; + DIR *tmp; + time_t time; + pid_t pid; + unsigned int sequence; + char *host; + time_t last_mod_time; + } +maildir_data; + +int maildir_open (mailbox *mbox); +int maildir_close (mailbox *mbox); +int maildir_delete (mailbox *mbox, unsigned int num); +int maildir_undelete (mailbox *mbox, unsigned int num); +int maildir_expunge (mailbox *mbox); +int maildir_scan (mailbox *mbox); +int maildir_is_deleted (mailbox *mbox, unsigned int num); +int maildir_is_updated (mailbox *mbox); +int maildir_lock (mailbox *mbox, mailbox_lock_t mode); +int maildir_add_message (mailbox *mbox, char *message); +char *maildir_get_body (mailbox *mbox, unsigned int num); +char *maildir_get_header (mailbox *mbox, unsigned int num); + +#endif |