Commit 9b8b34eb 9b8b34eb81da31559dc23927823fa0936cce6ad9 by Sean 'Shaleh' Perry

added mh.[ch]

cleaned up formatting of other files
1 parent 9a23cb9f
2000-05-15 Sean 'Shaleh' Perry <shaleh@debian.org>
* libmailbox/* ran some files thru emacs indent, I think I introduced
some oddness with vi
* libmailbox/mh.[ch] new files, based on maildir
the mh work is very empty -- just mh_open right now
2000-04-19 Jeff Bailey <jbailey@nisa.net>
* configure.in: Test for limits.h and inttypes.h, add malloc
......
......@@ -37,11 +37,10 @@
# include <paths.h>
#endif
#include <paths.h>
#include <mailbox.h>
#include <header.h>
/* FIXME: this should be in the mailbox header */
#ifndef _PATH_MAILDIR
# define _PATH_MAILDIR "/var/spool/mail"
#endif
......
......@@ -66,8 +66,8 @@ mbox_open (const char *name)
if (stat (mbox->name, &st) == -1)
{
free (mbox->name);
free (mbox);
return NULL; /* errno set by stat() */
free (mbox);
return NULL; /* errno set by stat() */
}
mbox->messages = 0;
......@@ -108,8 +108,8 @@ mbox_open (const char *name)
{
/* for example...
if (maildir_open (mbox, name) == 1)
return mbox;
*/
return mbox;
*/
errno = ENOSYS;
}
else
......@@ -153,12 +153,12 @@ mbox_header_line (mailbox *mbox, unsigned int num, const char *header)
if (!strncasecmp(&full[i], header, lh) && full[i+lh] == ':')
{
tmp = strdup (&full[i+lh+2]);
if (tmp == NULL)
{
free(full);
return NULL;
}
break;
if (tmp == NULL)
{
free(full);
return NULL;
}
break;
}
else
try = 0;
......@@ -189,7 +189,7 @@ mbox_header_line (mailbox *mbox, unsigned int num, const char *header)
else if (tmp[i] == '\n')
{
tmp[i] = '\0';
break;
break;
}
}
line = strdup (tmp);
......@@ -209,7 +209,7 @@ mbox_body_lines (mailbox *mbox, unsigned int num, unsigned int lines)
if (mbox == NULL)
{
errno = EINVAL;
return NULL;
return NULL;
}
if (lines == 0)
return strdup ("");
......@@ -226,7 +226,7 @@ mbox_body_lines (mailbox *mbox, unsigned int num, unsigned int lines)
{
full[i+1] = '\0';
buf = strdup (full);
break;
break;
}
}
}
......
/* 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 "mh.h"
/*
* Opens a mailbox
*/
int
mh_open (mailbox * mbox)
{
int i;
char old_dir[PATH_MAX];
struct dirent *entry;
mh_data *data;
if(mbox == NULL)
return EINVAL;
if(getcwd (old_dir, PATH_MAX) == NULL)
old_dir[0] = '\0';
chdir (mbox->name);
data = malloc (sizeof (mh_data));
data->dir = opendir (mbox->name);
if(data->dir == NULL)
return errno; /* set by opendir() */
/* process directory */
while ((entry = readdir (data->dir)) && (entry != NULL))
{
/* TODO: deal with mh dot files */
if (entry->d_name[0] == '.')
continue;
if (entry->d_name[0] == ',')
/* file marked for deletion */;
mbox->messages++;
}
#if 0
mbox->_data = data;
mbox->_close = mh_close;
mbox->_delete = mh_delete;
mbox->_undelete = mh_undelete;
mbox->_expunge = mh_expunge;
mbox->_add_message = mh_add_message;
mbox->_is_deleted = mh_is_deleted;
mbox->_lock = mh_lock;
mbox->_get_body = mh_get_body;
mbox->_get_header = mh_get_header;
#endif
chdir(old_dir);
fprintf(stderr, "%d messages read\n", mbox->messages);
return 0;
}
#if 0
/*
* Closes and unlocks a mailbox, does not expunge
*/
int
mh_close (mailbox * mbox)
{
/* FIXME: hack from unixmbox */
return 0;
}
/*
* Marks a message for deletion
*/
int
mh_delete (mailbox * mbox, unsigned int num)
{
mh_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
mh_undelete (mailbox * mbox, unsigned int num)
{
mh_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
mh_expunge (mailbox * mbox)
{
mh_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
mh_is_deleted (mailbox * mbox, unsigned int num)
{
mh_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
mh_is_updated (mailbox *mbox)
{
struct stat st;
mh_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
mh_add_message (mailbox * mbox, char *message)
{
/*
* FIXME: please write me
* http://www.qmail.org/man/man5/mh.html
*/
errno = ENOSYS;
return -1;
}
/*
* Returns a message body
*/
char *
mh_get_body (mailbox * mbox, unsigned int num)
{
mh_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 *
mh_get_header (mailbox * mbox, unsigned int num)
{
mh_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 Mh? no locking?
*/
int
mh_lock (mailbox *mbox, mailbox_lock_t mode)
{
return 0;
}
/* FIXME: not implemented */
int
mh_scan (mailbox *mbox)
{
errno = ENOSYS;
return -1;
}
#endif
/* 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 _MH_H
#define _MH_H 1
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <mailbox.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 _mh_message
{
off_t body;
char deleted;
}
mh_message;
typedef struct _mh_data
{
mh_message *messages;
DIR *dir;
unsigned int sequence;
}
mh_data;
int mh_open (mailbox *mbox);
int mh_close (mailbox *mbox);
int mh_delete (mailbox *mbox, unsigned int num);
int mh_undelete (mailbox *mbox, unsigned int num);
int mh_expunge (mailbox *mbox);
int mh_scan (mailbox *mbox);
int mh_is_deleted (mailbox *mbox, unsigned int num);
int mh_is_updated (mailbox *mbox);
int mh_lock (mailbox *mbox, mailbox_lock_t mode);
int mh_add_message (mailbox *mbox, char *message);
char *mh_get_body (mailbox *mbox, unsigned int num);
char *mh_get_header (mailbox *mbox, unsigned int num);
#endif
......@@ -36,7 +36,7 @@ unixmbox_open (mailbox * mbox)
if (mbox == NULL)
{
errno = EINVAL;
return -1;
return -1;
}
data = malloc (sizeof (unixmbox_data));
......@@ -67,7 +67,7 @@ unixmbox_open (mailbox * mbox)
if (stat (mbox->name, &st) == -1)
{
unixmbox_close (mbox);
return -1;
return -1;
}
data->last_mod_time = st.st_mtime;
......@@ -75,8 +75,8 @@ unixmbox_open (mailbox * mbox)
{
if (feof(data->file))
goto END; /* empty file, no messages */
unixmbox_close (mbox);
return -1;
unixmbox_close (mbox);
return -1;
}
if (strncmp (buf, "From ", 5))
{
......@@ -93,12 +93,12 @@ unixmbox_open (mailbox * mbox)
/* Beginning of a header */
while (strchr (buf, '\n') == NULL)
if (fgets (buf, 80, data->file) == NULL) /* eat the From line */
{
if (feof (data->file))
errno = EIO; /* corrupted mailbox? */
unixmbox_close (mbox);
return -1;
}
{
if (feof (data->file))
errno = EIO; /* corrupted mailbox? */
unixmbox_close (mbox);
return -1;
}
mbox->messages++;
......@@ -106,7 +106,7 @@ unixmbox_open (mailbox * mbox)
{
max_count = mbox->messages * 2;
data->messages = realloc (data->messages,
max_count * sizeof (unixmbox_message));
max_count * sizeof (unixmbox_message));
mbox->sizes = realloc (mbox->sizes, max_count * sizeof (int));
if (data->messages == NULL || mbox->sizes == NULL)
{
......@@ -142,7 +142,7 @@ unixmbox_open (mailbox * mbox)
return -1; /* errno is set */
}
END:
END:
mbox->_close = unixmbox_close;
mbox->_delete = unixmbox_delete;
mbox->_undelete = unixmbox_undelete;
......@@ -170,7 +170,7 @@ unixmbox_close (mailbox * mbox)
if (mbox == NULL)
{
errno = EINVAL;
return -1;
return -1;
}
data = mbox->_data;
unixmbox_lock (mbox, MO_ULOCK);
......@@ -255,52 +255,52 @@ unixmbox_expunge (mailbox * mbox)
if (mbox == NULL)
{
errno = EINVAL;
return -1;
return -1;
}
if (mbox->num_deleted)
{
data = mbox->_data;
fclose(data->file);
/* error handling */
data->file = NULL;
file = open(mbox->name, O_RDWR);
/* error handling */
for (i = 0; i < mbox->messages; i++)
{
if (data->messages[i].deleted == 0)
data = mbox->_data;
fclose(data->file);
/* error handling */
data->file = NULL;
file = open(mbox->name, O_RDWR);
/* error handling */
for (i = 0; i < mbox->messages; i++)
{
if (deletion_needed)
{
tmp = mbox->sizes[i];
if (tmp > buff_size)
{
buff_size = tmp;
buf = realloc (buf, tmp);
/* error checking */
}
lseek (file, data->messages[i].header, SEEK_SET);
size_read = read (file, buf, tmp);
/* error checking */
lseek (file, size, SEEK_SET);
write (file, buf, size_read);
/* error checking */
size += size_read;
}
else
{
size += mbox->sizes[i];
}
}
if (data->messages[i].deleted == 0)
{
if (deletion_needed)
{
tmp = mbox->sizes[i];
if (tmp > buff_size)
{
buff_size = tmp;
buf = realloc (buf, tmp);
/* error checking */
}
lseek (file, data->messages[i].header, SEEK_SET);
size_read = read (file, buf, tmp);
/* error checking */
lseek (file, size, SEEK_SET);
write (file, buf, size_read);
/* error checking */
size += size_read;
}
else
{
size += mbox->sizes[i];
}
}
else
{
deletion_needed = 1;
}
{
deletion_needed = 1;
}
}
close (file);
truncate (mbox->name, size);
free (buf);
}
close (file);
truncate (mbox->name, size);
free (buf);
}
return 0;
}
......@@ -335,7 +335,7 @@ unixmbox_is_updated (mailbox *mbox)
return -1;
}
if (stat (mbox->name, &st) == -1)
return -1;
return -1;
data = mbox->_data;
return (st.st_mtime > data->last_mod_time);
}
......@@ -368,7 +368,7 @@ unixmbox_get_body (mailbox * mbox, unsigned int num)
if (mbox == NULL)
{
errno = EINVAL;
return NULL;
return NULL;
}
if (num > mbox->messages || num < 0)
{
......@@ -412,7 +412,7 @@ unixmbox_get_header (mailbox * mbox, unsigned int num)
if ( mbox == NULL )
{
errno = EINVAL;
return NULL;
return NULL;
}
if (num > mbox->messages)
......@@ -474,6 +474,6 @@ void unixmbox_tester (mailbox *mbox, unsigned int num)
return;
printf ("Message size: %u\n", mbox->sizes[num]);
printf ("Message length: %lu\n",
data->messages[num].end - data->messages[num].header);
data->messages[num].end - data->messages[num].header);
}
#endif
......