Commit 3f5059d8 3f5059d80eca4eace1d79a9f41c4d2ea75b8f551 by Alain Magloire

mailbox.c mailbox.h mailboxi.c mbx_imap.c mbx_mbox.c

 	mbx_mdir.c mbx_mmdf.c mbx_pop.c mbx_unix.c

introduce an implementation of mbx_unix
1 parent 1918e4dd
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
......@@ -31,49 +31,62 @@
/* forward prototypes */
static int mbx_open (mailbox_t, int flag);
static int mbx_close (mailbox_t, int flag);
static int mbx_close (mailbox_t);
/* name */
static int mbx_get_name (mailbox_t, int *id, char *name, int offset, int n);
static int mbx_get_name (mailbox_t, int *id, char *name,
size_t len, size_t *n);
static int mbx_get_mname (mailbox_t mbox, int *id, char **name, size_t *n);
/* passwd */
static int mbx_get_passwd (mailbox_t, char *passwd, int offset, int len);
static int mbx_get_mpasswd (mailbox_t, char **passwd, int *len);
static int mbx_set_passwd (mailbox_t, const char *passwd, int offset, int n);
static int mbx_get_passwd (mailbox_t, char *passwd, size_t, size_t *);
static int mbx_get_mpasswd (mailbox_t, char **passwd, size_t *len);
static int mbx_set_passwd (mailbox_t, const char *passwd, size_t len);
/* deleting */
static int mbx_delete (mailbox_t, int id);
static int mbx_undelete (mailbox_t, int id);
static int mbx_delete (mailbox_t, size_t msgno);
static int mbx_undelete (mailbox_t, size_t msgno);
static int mbx_expunge (mailbox_t);
static int mbx_is_deleted (mailbox_t, int id);
static int mbx_is_deleted (mailbox_t, size_t msgno);
/* appending */
static int mbx_new_msg (mailbox_t, int *id);
static int mbx_set_header (mailbox_t, int id, const char *h,
int offset, int n, int replace);
static int mbx_set_body (mailbox_t, int id, const char *b,
int offset, int n, int replace);
static int mbx_append (mailbox_t, int id);
static int mbx_destroy_msg (mailbox_t, int id);
static int mbx_new_msg (mailbox_t, size_t *msgno);
static int mbx_set_header (mailbox_t, size_t msgno, const char *h,
size_t n, int replace);
static int mbx_set_body (mailbox_t, size_t msgno, const char *b,
size_t n, int replace);
static int mbx_append (mailbox_t, size_t msgno);
static int mbx_destroy_msg (mailbox_t, size_t msgno);
/* reading */
static int mbx_get_body (mailbox_t, int id, char *b, int offset, int n);
static int mbx_get_mbody (mailbox_t, int id, char **b, int *n);
static int mbx_get_header (mailbox_t, int id, char *h, int offset, int n);
static int mbx_get_mheader (mailbox_t, int id, char **h, int *n);
static int mbx_get_body (mailbox_t, size_t msgno, off_t off,
char *b, size_t len, size_t *n);
static int mbx_get_mbody (mailbox_t, size_t msgno, off_t off,
char **b, size_t *n);
static int mbx_get_header (mailbox_t, size_t msgno, off_t off,
char *h, size_t len, size_t *n);
static int mbx_get_mheader (mailbox_t, size_t msgno, off_t off,
char **h, size_t *n);
/* locking */
static int mbx_lock (mailbox_t, int flag);
static int mbx_unlock (mailbox_t);
//static int mbx_ilock (mailbox_t, int flag);
//static int mbx_iunlock (mailbox_t);
/* owner and group */
static int mbx_set_owner (mailbox_t, uid_t uid);
static int mbx_get_owner (mailbox_t, uid_t *uid);
static int mbx_set_group (mailbox_t, uid_t gid);
static int mbx_get_group (mailbox_t, uid_t *gid);
/* misc */
static int mbx_scan (mailbox_t, int *msgs);
static int mbx_scan (mailbox_t, size_t *msgs);
static int mbx_is_updated (mailbox_t);
static int mbx_get_timeout (mailbox_t, int *timeout);
static int mbx_set_timeout (mailbox_t, int timeout);
static int mbx_get_refresh (mailbox_t, int *refresh);
static int mbx_set_refresh (mailbox_t, int refresh);
static int mbx_get_size (mailbox_t, int id, size_t *size);
static int mbx_get_timeout (mailbox_t, size_t *timeout);
static int mbx_set_timeout (mailbox_t, size_t timeout);
static int mbx_get_refresh (mailbox_t, size_t *refresh);
static int mbx_set_refresh (mailbox_t, size_t refresh);
static int mbx_get_size (mailbox_t, size_t msgno, size_t *sh, size_t *sb);
static int mbx_set_notification (mailbox_t,
int (*func) (mailbox_t, void *arg));
......@@ -101,17 +114,18 @@ static struct mailbox_builtin
};
int
malibox_add_type (struct mailbox_type *mtype)
mailbox_add_type (struct mailbox_type *mtype)
{
struct mailbox_builtin *current = malloc (sizeof (*current));
if (current == NULL)
return -1;
return ENOMEM;
if (mtype->utype)
{
if (url_add_type (mtype->utype) < 0)
int status = url_add_type (mtype->utype);
if (status != 0)
{
free (current);
return -1;
return status;
}
mtype->id = mtype->utype->id; /* same ID as the url_type */
}
......@@ -142,37 +156,48 @@ mailbox_remove_type (struct mailbox_type *mtype)
return 0;;
}
}
return -1;
return EINVAL;
}
int
mailbox_list_type (struct mailbox_type *list, int n)
mailbox_list_type (struct mailbox_type *list, size_t len, size_t *n)
{
struct mailbox_builtin *current;
int i;
size_t i;
for (i = 0, current = mailbox_builtin->next; current != mailbox_builtin;
current = current->next, i++)
{
if (list)
if (i < n)
if (i < len)
list[i] = *(current->mtype);
}
return i;
if (n)
*n = i;
return 0;
}
int
mailbox_list_mtype (struct mailbox_type **mlist, int *n)
mailbox_list_mtype (struct mailbox_type **mlist, size_t *n)
{
struct mailbox_type *mtype;
int i;
size_t i = 0;
if ((i = mailbox_list_type (NULL, 0)) <= 0
|| (mtype = calloc (i, sizeof (*mtype))) == NULL)
mailbox_list_type (NULL, 0, &i);
if (i == 0)
{
if (n)
{
*n = i;
}
return 0;
}
mtype = calloc (i, sizeof (*mtype));
if (mtype == NULL)
{
return -1;
return ENOMEM;
}
*mlist = mtype;
return *n = mailbox_list_type (mtype, i);
return *n = mailbox_list_type (mtype, i, n);
}
int
......@@ -188,14 +213,14 @@ mailbox_get_type (struct mailbox_type **mtype, int id)
return 0;;
}
}
return -1;
return EINVAL;
}
int
mailbox_init (mailbox_t *mbox, const char *name, int id)
{
int status = -1; /* -1 means error */
int status = EINVAL;
/* 1st run: if they know what they want, shortcut */
if (id)
......@@ -262,6 +287,9 @@ mbx_check_struct (mailbox_t mbox)
if (mbox->_get_name == NULL)
mbox->_get_name = mbx_get_name;
if (mbox->_get_mname == NULL)
mbox->_get_mname = mbx_get_mname;
if (mbox->_get_passwd == NULL)
mbox->_get_passwd = mbx_get_passwd;
......@@ -316,12 +344,30 @@ mbx_check_struct (mailbox_t mbox)
if (mbox->_unlock == NULL)
mbox->_unlock = mbx_unlock;
if (mbox->_ilock == NULL)
mbox->_ilock = mbx_lock;
if (mbox->_iunlock == NULL)
mbox->_iunlock = mbx_unlock;
if (mbox->_scan == NULL)
mbox->_scan = mbx_scan;
if (mbox->_is_updated == NULL)
mbox->_is_updated = mbx_is_updated;
if (mbox->_set_owner == NULL)
mbox->_set_owner = mbx_set_owner;
if (mbox->_get_owner == NULL)
mbox->_get_owner = mbx_get_owner;
if (mbox->_set_group == NULL)
mbox->_set_group = mbx_set_group;
if (mbox->_get_group == NULL)
mbox->_get_group = mbx_get_group;
if (mbox->_get_timeout == NULL)
mbox->_get_timeout = mbx_get_timeout;
......@@ -346,233 +392,259 @@ mbx_check_struct (mailbox_t mbox)
static int
mbx_open (mailbox_t mbox, int flag)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_close (mailbox_t mbox, int flag)
mbx_close (mailbox_t mbox)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
/* name */
static int
mbx_get_name (mailbox_t mbox, int *id, char *name, int offset, int n)
mbx_get_name (mailbox_t mbox, int *id, char *name, size_t len, size_t *n)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_get_mname (mailbox_t mbox, int *id, char **name, size_t *n)
{
size_t i = 0;
mbox->_get_name (mbox, id, 0, 0, &i);
i++;
*name = calloc (i, sizeof (char));
if (*name == NULL)
{
return ENOMEM;
}
mbox->_get_name (mbox, id, *name, i, n);
return 0;
}
/* passwd */
static int
mbx_get_passwd (mailbox_t mbox, char *passwd, int offset, int len)
mbx_get_passwd (mailbox_t mbox, char *passwd, size_t len, size_t *n)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_get_mpasswd (mailbox_t mbox, char **passwd, int *len)
mbx_get_mpasswd (mailbox_t mbox, char **passwd, size_t *n)
{
int i;
char *p;
if ((i = mbox->_get_passwd (mbox, NULL, 0, 0)) <= 0
|| (p = calloc (i, sizeof (*p))) == NULL)
size_t i = 0;
mbox->_get_passwd (mbox, NULL, 0, &i);
i++;
*passwd = calloc (i, sizeof (char));
if (*passwd == NULL)
{
return -1;
return ENOMEM;
}
*passwd = p;
return *len = i;
mbox->_get_passwd (mbox, *passwd, i, n);
return 0;
}
static int
mbx_set_passwd (mailbox_t mbox, const char *passwd, int offset, int n)
mbx_set_passwd (mailbox_t mbox, const char *passwd, size_t len)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
/* deleting */
static int
mbx_delete (mailbox_t mbox, int id)
mbx_delete (mailbox_t mbox, size_t msgno)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_undelete (mailbox_t mbox, int id)
mbx_undelete (mailbox_t mbox, size_t msgno)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_expunge (mailbox_t mbox)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_is_deleted (mailbox_t mbox, int id)
mbx_is_deleted (mailbox_t mbox, size_t msgno)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
/* appending */
static int
mbx_new_msg (mailbox_t mbox, int *id)
mbx_new_msg (mailbox_t mbox, size_t *msgno)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_set_header (mailbox_t mbox, int id, const char *h,
int offset, int n, int replace)
mbx_set_header (mailbox_t mbox, size_t msgno, const char *h,
size_t len, int replace)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_set_body (mailbox_t mbox, int id, const char *b,
int offset, int n, int replace)
mbx_set_body (mailbox_t mbox, size_t msgno, const char *b,
size_t len, int replace)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_append (mailbox_t mbox, int id)
mbx_append (mailbox_t mbox, size_t msgno)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_destroy_msg (mailbox_t mbox, int id)
mbx_destroy_msg (mailbox_t mbox, size_t msgno)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
/* reading */
static int
mbx_get_body (mailbox_t mbox, int id, char *b, int offset, int n)
mbx_get_body (mailbox_t mbox, size_t msgno, off_t off,
char *b, size_t len, size_t *n)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_get_mbody (mailbox_t mbox, int id, char **body, int *len)
{
int i;
char *b;
if ((i = mbox->_get_body (mbox, id, NULL, 0, 0)) <= 0
|| (b = calloc (i, sizeof (*b))) == NULL)
mbx_get_mbody (mailbox_t mbox, size_t msgno, off_t off,
char **body, size_t *n)
{
size_t i = 0;
mbox->_get_body (mbox, msgno, off, NULL, 0, &i);
i++;
*body = calloc (i, sizeof (char));
if (*body == NULL)
{
return -1;
return ENOMEM;
}
*body = b;
return *len = i;
mbox->_get_body (mbox, msgno, off, *body, i, n);
return 0;
}
static int
mbx_get_header (mailbox_t mbox, int id, char *h, int offset, int n)
mbx_get_header (mailbox_t mbox, size_t msgno, off_t off,
char *h, size_t len, size_t *n)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_get_mheader (mailbox_t mbox, int id, char **header, int *len)
{
int i;
char *h;
if ((i = mbox->_get_header (mbox, id, NULL, 0, 0)) <= 0
|| (h = calloc (i, sizeof (*h))) == NULL)
mbx_get_mheader (mailbox_t mbox, size_t msgno, off_t off,
char **header, size_t *n)
{
size_t i;
i = mbox->_get_header (mbox, msgno, off, NULL, 0, &i);
i++;
*header = calloc (i, sizeof (char));
if (*header == NULL)
{
return -1;
return ENOMEM;
}
*header = h;
return *len = i;
mbox->_get_header (mbox, msgno, off, *header, i, n);
return 0;
}
/* locking */
static int
mbx_lock (mailbox_t mbox, int flag)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_unlock (mailbox_t mbox)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
/* owner and group */
static int
mbx_set_owner (mailbox_t mbox, uid_t uid)
{
mbox->owner = uid;
return 0;
}
static int
mbx_get_owner (mailbox_t mbox, uid_t *uid)
{
*uid = mbox->owner;
return 0;
}
static int
mbx_set_group (mailbox_t mbox, uid_t gid)
{
mbox->group = gid;
return 0;
}
static int
mbx_get_group (mailbox_t mbox, uid_t *gid)
{
*gid = mbox->group;
return 0;
}
/* misc */
static int
mbx_scan (mailbox_t mbox, int *msgs)
mbx_scan (mailbox_t mbox, size_t *msgs)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_is_updated (mailbox_t mbox)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_get_timeout (mailbox_t mbox, int *timeout)
mbx_get_timeout (mailbox_t mbox, size_t *timeout)
{
errno = ENOSYS;
return -1;
*timeout = mbox->timeout;
return 0;
}
static int
mbx_set_timeout (mailbox_t mbox, int timeout)
mbx_set_timeout (mailbox_t mbox, size_t timeout)
{
errno = ENOSYS;
return -1;
mbox->timeout = timeout;
return 0;
}
static int
mbx_get_refresh (mailbox_t mbox, int *refresh)
mbx_get_refresh (mailbox_t mbox, size_t *refresh)
{
errno = ENOSYS;
return -1;
*refresh = mbox->refresh;
return 0;
}
static int
mbx_set_refresh (mailbox_t mbox, int refresh)
mbx_set_refresh (mailbox_t mbox, size_t refresh)
{
errno = ENOSYS;
return -1;
mbox->refresh = refresh;
return 0;
}
static int
mbx_get_size (mailbox_t mbox, int id, size_t *size)
mbx_get_size (mailbox_t mbox, size_t msgno, size_t *sh, size_t *sb)
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
static int
mbx_set_notification (mailbox_t mbox, int (*func) (mailbox_t, void *arg))
{
errno = ENOSYS;
return -1;
return ENOSYS;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
......@@ -19,6 +19,8 @@
# define _MAILBOX_H
#include <url.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#ifdef __cplusplus
......@@ -52,77 +54,98 @@ struct mailbox_type
struct _mailbox
{
/* Data */
char *name;
int messages;
int num_deleted;
long size;
int timeout;
int refresh;
mailbox_lock_t lock;
int (*func) __P ((mailbox_t));
uid_t owner;
gid_t group;
size_t messages;
size_t num_deleted;
off_t size;
int lock;
size_t timeout;
size_t refresh;
int (*func) __P ((mailbox_t, void *arg));
struct mailbox_type *mtype;
/* back pointer to the specific mailbox */
void *data;
struct mailbox_type *mtype;
/* Functions */
//void (*_destroy) __P ((mailbox_t *));
#define MU_MB_RDONLY ((int)1)
#define MU_MB_WRONLY (MU_MB_RDONLY << 1)
#define MU_MB_RDWR (MU_MB_WRONLY << 1)
#define MU_MB_APPEND (MU_MB_RDWR << 1)
#define MU_MB_CREAT (MU_MB_APPEND << 1)
int (*_open) __P ((mailbox_t, int flag));
int (*_close) __P ((mailbox_t, int flag));
int (*_close) __P ((mailbox_t));
/* type */
int (*_get_name) __P ((mailbox_t, int *id, char *name,
int offset, int len));
int (*_get_mname) __P ((mailbox_t, int *id, char **name,
int *len));
size_t len, size_t *n));
int (*_get_mname) __P ((mailbox_t, int *id, char **name, size_t *n));
/* passwd if needed */
int (*_get_passwd) __P ((mailbox_t, char * passwd, int offset, int n));
int (*_get_mpasswd) __P ((mailbox_t, char **passwd, int *n));
int (*_set_passwd) __P ((mailbox_t, const char * passwd,
int offset, int n));
int (*_get_passwd) __P ((mailbox_t, char *passwd,
size_t len, size_t *n));
int (*_get_mpasswd) __P ((mailbox_t, char **passwd, size_t *n));
int (*_set_passwd) __P ((mailbox_t, const char *passwd, size_t len));
/* deleting mesgs */
int (*_delete) __P ((mailbox_t, int id));
int (*_undelete) __P ((mailbox_t, int id));
int (*_is_deleted) __P ((mailbox_t, int id));
int (*_is_deleted) __P ((mailbox_t, size_t msgno));
int (*_delete) __P ((mailbox_t, size_t msgno));
int (*_undelete) __P ((mailbox_t, size_t msgno));
int (*_expunge) __P ((mailbox_t));
int (*_is_updated) __P ((mailbox_t));
int (*_scan) __P ((mailbox_t, size_t *msgs));
/* appending messages */
int (*_new_msg) __P ((mailbox_t, int *id));
int (*_set_header) __P ((mailbox_t, int id, const char *h,
int offset, int n, int replace));
int (*_set_body) __P ((mailbox_t, int id, const char *b,
int offset, int n, int replace));
int (*_append) __P ((mailbox_t, int id));
int (*_destroy_msg) __P ((mailbox_t, int id));
int (*_new_msg) __P ((mailbox_t, size_t *msgno));
int (*_set_header) __P ((mailbox_t, size_t msgno, const char *h,
size_t len, int replace));
int (*_set_body) __P ((mailbox_t, size_t msgno, const char *b,
size_t len, int replace));
int (*_append) __P ((mailbox_t, size_t msgno));
int (*_destroy_msg) __P ((mailbox_t, size_t msgno));
#define MU_MB_RDLOCK 0
#define MU_MB_WRLOCK 1
/* locking */
int (*_lock) __P ((mailbox_t, int flag));
int (*_unlock) __P ((mailbox_t));
int (*_ilock) __P ((mailbox_t, int flag));
int (*_iunlock) __P ((mailbox_t));
/* reading mesgs */
int (*_get_body) __P ((mailbox_t, int id, char *v,
int offset, int n));
int (*_get_mbody) __P ((mailbox_t, int id, char **v, int *n));
int (*_get_header) __P ((mailbox_t, int id, char *h,
int offset, int n));
int (*_get_mheader) __P ((mailbox_t, int id, char **h, int *n));
int (*_get_body) __P ((mailbox_t, size_t msgno, off_t off,
char *b, size_t len, size_t *n));
int (*_get_mbody) __P ((mailbox_t, size_t msgno, off_t off,
char **b, size_t *n));
int (*_get_header) __P ((mailbox_t, size_t msgno, off_t off,
char *h, size_t len, size_t *n));
int (*_get_mheader) __P ((mailbox_t, size_t msgno, off_t off,
char **h, size_t *n));
int (*_get_size) __P ((mailbox_t, size_t msgno,
size_t *h, size_t *b));
/* setting flags */
int (*_msg_is_read) __P ((mailbox_t, int id));
int (*_msg_set_read) __P ((mailbox_t, int id));
int (*_msg_is_seen) __P ((mailbox_t, int id));
int (*_msg_set_seen) __P ((mailbox_t, int id));
int (*_is_read) __P ((mailbox_t, size_t msgno));
int (*_set_read) __P ((mailbox_t, size_t msgno));
int (*_is_seen) __P ((mailbox_t, size_t msgno));
int (*_set_seen) __P ((mailbox_t, size_t msgno));
/* owner and group */
int (*_set_owner) __P ((mailbox_t, uid_t uid));
int (*_get_owner) __P ((mailbox_t, uid_t *uid));
int (*_set_group) __P ((mailbox_t, gid_t gid));
int (*_get_group) __P ((mailbox_t, gid_t *gid));
/* miscellany */
int (*_scan) __P ((mailbox_t, int *msgs));
int (*_is_updated) __P ((mailbox_t));
int (*_get_timeout) __P ((mailbox_t, int *timeout));
int (*_set_timeout) __P ((mailbox_t, int timeout));
int (*_get_size) __P ((mailbox_t, int id, size_t *size));
int (*_get_refresh) __P ((mailbox_t, int *refresh));
int (*_set_refresh) __P ((mailbox_t, int refresh));
int (*_size) __P ((mailbox_t, off_t *size));
int (*_get_timeout) __P ((mailbox_t, size_t *timeout));
int (*_set_timeout) __P ((mailbox_t, size_t timeout));
int (*_get_refresh) __P ((mailbox_t, size_t *refresh));
int (*_set_refresh) __P ((mailbox_t, size_t refresh));
int (*_set_notification) __P ((mailbox_t,
int (*func) __P ((mailbox_t, void * arg))));
};
......@@ -132,8 +155,9 @@ extern int mailbox_init __P ((mailbox_t *, const char *name, int id));
extern void mailbox_destroy __P ((mailbox_t *));
/* mailbox registration */
extern int mailbox_list_type __P ((struct mailbox_type mtype[], int size));
extern int mailbox_list_mtype __P ((struct mailbox_type *mtype[], int *size));
extern int mailbox_list_type __P ((struct mailbox_type mtype[],
size_t len, size_t *n));
extern int mailbox_list_mtype __P ((struct mailbox_type **mtype, size_t *n));
extern int mailbox_add_type __P ((struct mailbox_type *mtype));
extern int mailbox_remove_type __P ((struct mailbox_type *mtype));
extern int mailbox_get_type __P ((struct mailbox_type **mtype, int id));
......@@ -147,97 +171,112 @@ extern int mailbox_get_type __P ((struct mailbox_type **mtype, int id));
#endif
extern INLINE int mailbox_open __P ((mailbox_t, int flag));
extern INLINE int mailbox_close __P ((mailbox_t, int flag));
extern INLINE int mailbox_close __P ((mailbox_t));
/* type */
extern INLINE int mailbox_get_name __P ((mailbox_t, int *id, char *name,
int offset, int len));
size_t len, size_t *n));
extern INLINE int mailbox_get_mname __P ((mailbox_t, int *id, char **name,
int *len));
size_t *n));
/* passwd */
extern INLINE int mailbox_get_passwd __P ((mailbox_t, char *passwd,
int offset, int len));
size_t len, size_t *n));
extern INLINE int mailbox_get_mpasswd __P ((mailbox_t, char **passwd,
int *len));
size_t *n));
extern INLINE int mailbox_set_passwd __P ((mailbox_t, const char *passwd,
int offset, int len));
size_t len));
/* deleting */
extern INLINE int mailbox_delete __P ((mailbox_t, int));
extern INLINE int mailbox_undelete __P ((mailbox_t, int));
extern INLINE int mailbox_delete __P ((mailbox_t, size_t msgno));
extern INLINE int mailbox_undelete __P ((mailbox_t, size_t msgno));
extern INLINE int mailbox_expunge __P ((mailbox_t));
extern INLINE int mailbox_is_deleted __P ((mailbox_t, int));
extern INLINE int mailbox_is_deleted __P ((mailbox_t, size_t msgno));
/* appending */
extern INLINE int mailbox_new_msg __P ((mailbox_t, int * id));
extern INLINE int mailbox_set_header __P ((mailbox_t, int id, const char *h,
int offset, int n, int replace));
extern INLINE int mailbox_set_body __P ((mailbox_t, int id, const char *b,
int offset, int n, int replace));
extern INLINE int mailbox_append __P ((mailbox_t, int id));
extern INLINE int mailbox_destroy_msg __P ((mailbox_t, int id));
extern INLINE int mailbox_new_msg __P ((mailbox_t, size_t * msgno));
extern INLINE int mailbox_set_header __P ((mailbox_t, size_t msgno,
const char *h, size_t len,
int replace));
extern INLINE int mailbox_set_body __P ((mailbox_t, size_t msgno,
const char *b, size_t len,
int replace));
extern INLINE int mailbox_append __P ((mailbox_t, size_t msgno));
extern INLINE int mailbox_destroy_msg __P ((mailbox_t, size_t msgno));
/* reading */
extern INLINE int mailbox_get_body __P ((mailbox_t, int id, char *b,
int offset, int n));
extern INLINE int mailbox_get_mbody __P ((mailbox_t, int id, char **b,
int *n));
extern INLINE int mailbox_get_header __P ((mailbox_t, int id, char *h,
int offset, int n));
extern INLINE int mailbox_get_mheader __P ((mailbox_t, int id, char **h,
int *n));
extern INLINE int mailbox_get_body __P ((mailbox_t, size_t msgno,
off_t off, char *b,
size_t len, size_t *n));
extern INLINE int mailbox_get_mbody __P ((mailbox_t, size_t msgno, off_t off,
char **b, size_t *n));
extern INLINE int mailbox_get_header __P ((mailbox_t, size_t msgno, off_t off,
char *h, size_t len, size_t *n));
extern INLINE int mailbox_get_mheader __P ((mailbox_t, size_t msgno, off_t off,
char **h, size_t *n));
/* locking */
extern INLINE int mailbox_lock __P ((mailbox_t, int flag));
extern INLINE int mailbox_unlock __P ((mailbox_t));
/* owner and group */
extern INLINE int mailbox_set_owner __P ((mailbox_t, uid_t uid));
extern INLINE int mailbox_set_group __P ((mailbox_t, gid_t gid));
/* miscellany */
extern INLINE int mailbox_scan __P ((mailbox_t, int *msgs));
extern INLINE int mailbox_scan __P ((mailbox_t, size_t *msgs));
extern INLINE int mailbox_is_updated __P ((mailbox_t));
extern INLINE int mailbox_get_timeout __P ((mailbox_t, int *timeout));
extern INLINE int mailbox_set_timeout __P ((mailbox_t, int timeout));
extern INLINE int mailbox_get_refresh __P ((mailbox_t, int *refresh));
extern INLINE int mailbox_set_refresh __P ((mailbox_t, int refresh));
extern INLINE int mailbox_get_size __P ((mailbox_t, int id, size_t *size));
extern INLINE int mailbox_set_notification __P ((mailbox_t, int
(*func) __P ((mailbox_t))));
extern INLINE int mailbox_get_timeout __P ((mailbox_t, size_t *timeout));
extern INLINE int mailbox_set_timeout __P ((mailbox_t, size_t timeout));
extern INLINE int mailbox_get_refresh __P ((mailbox_t, size_t *refresh));
extern INLINE int mailbox_set_refresh __P ((mailbox_t, size_t refresh));
extern INLINE int mailbox_get_size __P ((mailbox_t, size_t msgno,
size_t *header, size_t *body));
extern INLINE int mailbox_set_notification __P ((mailbox_t,
int (*func)
__P ((mailbox_t, void *))));
#ifdef MU_USE_MACROS
#define mailbox_open(m, f) m->_open (m, f)
#define mailbox_close(m, f) m->_close (m, f)
#define mailbox_close(m) m->_close (m)
/* type */
#define mailbox_get_name(m, t, d, o, n) m->_get_name (m, t, d, o, n)
#define mailbox_get_name(m, t, d, l, n) m->_get_name (m, t, d, l, n)
#define mailbox_get_mtype(m, t, d, n) m->_get_mtype (m, t, d, n)
/* passwd */
#define mailbox_get_passwd(m, p, o, n) m->_get_passwd (m, p, o, n)
#define mailbox_get_passwd(m, p, l, n) m->_get_passwd (m, p, l, n)
#define mailbox_get_mpasswd(m, p, n) m->_get_mpasswd (m, p, n)
#define mailbox_set_passwd(m, p, o, n) m->_set_passwd (m, p, o, n)
#define mailbox_set_passwd(m, p, l) m->_set_passwd (m, p, l)
/* deleting */
#define mailbox_delete(m, id) m->_delete (m, id)
#define mailbox_undelete(m, id) m->_undelete (m, id)
#define mailbox_is_deleted(m, id) m->_is_deleted (m, id)
#define mailbox_delete(m, mid) m->_delete (m, mid)
#define mailbox_undelete(m, mid) m->_undelete (m, mid)
#define mailbox_is_deleted(m, mid) m->_is_deleted (m, mid)
#define mailbox_expunge(m) m->_expunge (m)
/* appending */
#define mailbox_new_msg(m, id) m->_new_msg (m, id)
#define mailbox_set_header(m, id, h, o, n, r) m->_set_header(m, id, h, o, n, r)
#define mailbox_set_body(m, id, b, o, n, r) m->_set_body (m, id, b, o, n, r)
#define mailbox_append(m, id) m->_append (m, id)
#define mailbox_destroy_msg(m, id) m->_destroy_msg (m, id)
#define mailbox_new_msg(m, mid) m->_new_msg (m, mid)
#define mailbox_set_header(m, mid, h, l, r) m->_set_header(m, mid, h, n, r)
#define mailbox_set_body(m, mid, b, l r) m->_set_body (m, mid, b, l, r)
#define mailbox_append(m, mid) m->_append (m, mid)
#define mailbox_destroy_msg(m, mid) m->_destroy_msg (m, mid)
/* locking */
#define mailbox_lock(m, f) m->_lock (m, f)
#define mailbox_unlock(m) m->_unlock (m)
/* reading */
#define mailbox_get_header(m, id, h, o, n) m->_get_header (m, id, h, o, n)
#define mailbox_get_mheader(m, id, h, n) m->_get_header (m, id, h, n)
#define mailbox_get_body(m, id, b, o, n) m->_get_body (m, id, b, o, n)
#define mailbox_get_mbody(m, id, b, n) m->_get_body (m, id, b, n)
#define mailbox_get_header(m, mid, h, l, n) m->_get_header (m, mid, h, o, n)
#define mailbox_get_mheader(m, mid, h, l) m->_get_header (m, mid, h, l)
#define mailbox_get_body(m, mid, b, l, n) m->_get_body (m, mid, b, l, n)
#define mailbox_get_mbody(m, mid, b, n) m->_get_body (m, mid, b, n)
/* owner and group */
#define mailbox_set_owner(m, uid) m->_set_owner(m, uid)
#define mailbox_get_owner(m, uid) m->_set_owner(m, uid)
#define mailbox_set_group(m, gid) m->_set_group(m, gid)
#define mailbox_get_group(m, gid) m->_set_group(m, gid)
/* miscellany */
#define mailbox_scan(m, t) m->_scan (m, t)
......@@ -246,7 +285,7 @@ extern INLINE int mailbox_set_notification __P ((mailbox_t, int
#define mailbox_set_timeout(m, t) m->_set_timeout (m, t)
#define mailbox_get_refresh(m, r) m->_get_refresh (m, r)
#define mailbox_set_refresh(m, r) m->_set_refresh (m, r)
#define mailbox_get_size(m, id, size) m->_get_size(m, id, size)
#define mailbox_get_size(m, mid, sh, sb) m->_get_size(m, mid, sh, sb)
#define mailbox_set_notification(m, func) m->_set_notification (m, func)
#endif /* MU_USE_MACROS */
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
......@@ -24,57 +24,44 @@ mailbox_open (mailbox_t mbox, int flag)
}
int
mailbox_close (mailbox_t mbox, int flag)
mailbox_close (mailbox_t mbox)
{
return mbox->_close (mbox, flag);
}
/* type */
int
mailbox_get_type (mailbox_t mbox, int *type, char *desc, int offset, int len)
{
return mbox->_get_type (mbox, type, desc, offset, len);
}
int
mailbox_get_mtype (mailbox_t mbox, int *type, char **desc, int *len)
{
return mbox->_get_mtype (mbox, type, desc, offset, len);
return mbox->_close (mbox);
}
/* passwd */
int
mailbox_get_passwd (mailbox_t mbox, char *passwd, int offset, int len)
mailbox_get_passwd (mailbox_t mbox, char *passwd, size_t len, size_t *n)
{
return mbox->_get_passwd (mbox, passwd, offset, len);
return mbox->_get_passwd (mbox, passwd, len, n);
}
int
mailbox_get_mpasswd (mailbox_t mbox, char **passwd, int *len)
mailbox_get_mpasswd (mailbox_t mbox, char **passwd, size_t *n)
{
return mbox->_get_mpasswd (mbox, passwd, len);
return mbox->_get_mpasswd (mbox, passwd, n);
}
int
mailbox_set_passwd (mailbox_t mbox, const char *passwd, int offset, int len)
mailbox_set_passwd (mailbox_t mbox, const char *passwd,
size_t len)
{
return mbox->_set_passwd (mbox, passwd, offset, len);
return mbox->_set_passwd (mbox, passwd, len);
}
/* deleting */
int
mailbox_delete (mailbox_t mbox, int id)
mailbox_delete (mailbox_t mbox, size_t msgno)
{
return mbox->_delete (mbox, id);
return mbox->_delete (mbox, msgno);
}
int
mailbox_undelete (mailbox_t mbox, int id)
mailbox_undelete (mailbox_t mbox, size_t msgno)
{
return mbox->_undelete (mbox, id);
return mbox->_undelete (mbox, msgno);
}
int
......@@ -84,69 +71,73 @@ mailbox_expunge (mailbox_t mbox)
}
int
mailbox_is_deleted (mailbox_t mbox, int)
mailbox_is_deleted (mailbox_t mbox, size_t msgno)
{
return mbox->_is_deleted (mbox, int);
return mbox->_is_deleted (mbox, msgno);
}
/* appending */
int
mailbox_new_msg (mailbox_t mbox, int * id)
mailbox_new_msg (mailbox_t mbox, size_t *msgno)
{
return mbox->_new_msg (mbox, id);
return mbox->_new_msg (mbox, msgno);
}
int
mailbox_set_header (mailbox_t mbox, int id, const char *h,
int offset, int n, int replace)
mailbox_set_header (mailbox_t mbox, size_t msgno, const char *h,
size_t len, int replace)
{
return mbox->_set_header (mbox, id, h, offset, n, replace);
return mbox->_set_header (mbox, msgno, h, len, replace);
}
int
mailbox_set_body (mailbox_t mbox, int id, const char *b,
int offset, int n, int replace)
mailbox_set_body (mailbox_t mbox, size_t msgno, const char *b,
size_t len, int replace)
{
return mbox->_set_body (mbox, id, b, offset, n, replace);
return mbox->_set_body (mbox, msgno, b, len, replace);
}
int
mailbox_append (mailbox_t mbox, int id)
mailbox_append (mailbox_t mbox, size_t msgno)
{
return mbox->_append (mbox, id);
return mbox->_append (mbox, msgno);
}
int
mailbox_destroy_msg (mailbox_t mbox, int id)
mailbox_destroy_msg (mailbox_t mbox, size_t msgno)
{
return mbox->_destroy_msg (mbox, id);
return mbox->_destroy_msg (mbox, msgno);
}
/* reading */
int
mailbox_get_body (mailbox_t mbox, int id, char *b, int offset, int n)
mailbox_get_body (mailbox_t mbox, size_t msgno, off_t off, char *b,
size_t len, size_t *n)
{
return mbox->_get_body (mbox, id, b, offset, n);
return mbox->_get_body (mbox, msgno, off, b, len, n);
}
int
mailbox_get_mbody (mailbox_t mbox, int id, char **b, int *n)
mailbox_get_mbody (mailbox_t mbox, size_t msgno, off_t off,
char **b, size_t *n)
{
return mbox->_get_body (mbox, id, b, n);
return mbox->_get_mbody (mbox, msgno, off, b, n);
}
int
mailbox_get_header (mailbox_t mbox, int id, char *h, int offset, int n)
mailbox_get_header (mailbox_t mbox, size_t msgno, off_t off, char *h,
size_t len, size_t *n)
{
return mbox->_get_header (mbox, id, h, offset, n);
return mbox->_get_header (mbox, msgno, off, h, len, n);
}
int
mailbox_get_mheader (mailbox_t mbox, int id, char **h, int *n)
mailbox_get_mheader (mailbox_t mbox, size_t msgno, off_t off,
char **h, size_t *n)
{
return mbox->_get_header (mbox, id, h, n);
return mbox->_get_mheader (mbox, msgno, off, h, n);
}
......@@ -166,7 +157,7 @@ mailbox_unlock (mailbox_t mbox)
/* misc */
int
mailbox_scan (mailbox_t mbox, int *msgs)
mailbox_scan (mailbox_t mbox, size_t *msgs)
{
return mbox->_scan (mbox, msgs);
}
......@@ -178,31 +169,32 @@ mailbox_is_updated (mailbox_t mbox)
}
int
mailbox_get_timeout (mailbox_t mbox, int *timeout)
mailbox_get_timeout (mailbox_t mbox, size_t *timeout)
{
return mbox->_get_timeout (mbox, timeout);
}
int
mailbox_set_timeout (mailbox_t mbox, int timeout)
mailbox_set_timeout (mailbox_t mbox, size_t timeout)
{
return mbox->_set_timeout (mbox, timeout);
}
int
mailbox_get_refresh (mailbox_t mbox, int *refresh)
mailbox_get_refresh (mailbox_t mbox, size_t *refresh)
{
return mbox->_get_refresh (mbox, refresh);
}
int
mailbox_set_refresh (mailbox_t mbox, int refresh)
mailbox_set_refresh (mailbox_t mbox, size_t refresh)
{
return mbox->_set_refresh (mbox, refresh);
}
int
mailbox_set_notification (mailbox_t mbox, int (*notif) __P ((mailbox_t mbox)))
mailbox_set_notification (mailbox_t mbox,
int (*notif) __P ((mailbox_t, void *)))
{
return mbox->_set_notification (mbox, notif);
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
......@@ -17,6 +17,7 @@
#include <mbx_imap.h>
#include <url_imap.h>
#include <errno.h>
struct mailbox_type _mailbox_imap_type =
......@@ -35,5 +36,5 @@ mailbox_imap_destroy (mailbox_t *mbox)
int
mailbox_imap_init (mailbox_t *mbox, const char *name)
{
return -1;
return ENOSYS;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
......@@ -59,7 +59,7 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name)
*/
if (stat (name, &st) == -1)
{
return -1; /* errno set by stat () */
return errno; /* errno set by stat () */
}
if (S_ISREG (st.st_mode))
......@@ -77,7 +77,7 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name)
if (fd == -1)
{
/* Oops !! wrong permission ? file deleted ? */
return -1; /* errno set by open () */
return errno; /* errno set by open () */
}
/* Read a small chunck */
......@@ -91,6 +91,7 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name)
*/
if (count == 0) /*empty file*/
{
close (fd);
return mailbox_unix_init (mbox, name);
}
......@@ -99,11 +100,13 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name)
if (strncmp (head, "From ", 5) == 0)
{
/* This is Unix Mbox */
close (fd);
return mailbox_unix_init (mbox, name);
}
}
/* Try MMDF */
close (fd);
#endif
return mailbox_unix_init (mbox, name);
}
......@@ -121,5 +124,5 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name)
void
mailbox_mbox_destroy (mailbox_t *mbox)
{
return (*mbox)->mtype->_destroy (mbox);
(*mbox)->mtype->_destroy (mbox);
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library 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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <url_mdir.h>
#include <mbx_mdir.h>
#include <errno.h>
struct mailbox_type _mailbox_maildir_type =
{
......@@ -11,7 +29,7 @@ struct mailbox_type _mailbox_maildir_type =
int
mailbox_maildir_init (mailbox_t *mbox, const char *name)
{
return -1;
return ENOSYS;
}
void
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library 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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <url_mmdf.h>
#include <mbx_mmdf.h>
#include <errno.h>
struct mailbox_type _mailbox_maildir_type =
struct mailbox_type _mailbox_mmdf_type =
{
"MMDF",
(int)&_url_mmdf_type, &_url_mmdf_type,
......@@ -11,7 +29,7 @@ struct mailbox_type _mailbox_maildir_type =
int
mailbox_mmdf_init (mailbox_t *mbox, const char *name)
{
return -1;
return ENOSYS;
}
void
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
......@@ -17,6 +17,7 @@
#include <url_pop.h>
#include <mbx_pop.h>
#include <errno.h>
struct mailbox_type _mailbox_pop_type =
{
......@@ -34,5 +35,5 @@ mailbox_pop_destroy (mailbox_t *mbox)
int
mailbox_pop_init (mailbox_t *mbox, const char *name)
{
return -1;
return ENOSYS;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library 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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <url_unix.h>
#include <mbx_unix.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <ctype.h>
struct mailbox_type _mailbox_unix_type =
{
......@@ -20,146 +47,1178 @@ typedef struct _mailbox_unix_msg
off_t body;
off_t end;
int deleted;
} mailbox_unix_msg_t;
int is_read;
int is_seen;
} *mailbox_unix_msg_t;
typedef struct _mailbox_unix_data
{
mailbox_unix_msg_t *messages;
mailbox_unix_msg_t messages;
FILE *file;
mailbox_lock_t lockmode;
time_t last_mode_time;
} mailbox_unix_data_t;
char *dirname;
char *basename;
#ifdef HAVE_PTHREAD_H
pthread_mutex_t mutex;
#endif
int lock;
int ilock;
time_t mtime;
size_t size;
} *mailbox_unix_data_t;
/* forward prototypes */
static int mailbox_unix_open (mailbox_t *mbox, const char *name);
static int mailbox_unix_close (mailbox_t *mbox);
static int mailbox_unix_open (mailbox_t mbox, int flag);
static int mailbox_unix_close (mailbox_t mbox);
static int mailbox_unix_get_name (mailbox_t, int *id, char *name,
int offset, int len);
static int mailbox_unix_get_mname (mailbox_t, int *id, char **name, int *len);
size_t len, size_t *n);
/* passwd */
static int mailbox_unix_get_passwd (mailbox_t, char *passwd,
int offset, int len);
static int mailbox_unix_get_mpasswd (mailbox_t, char **passwd, int *len);
static int mailbox_unix_set_passwd (mailbox_t, const char *passwd,
int offset, int len);
/* deleting */
static int mailbox_unix_delete (mailbox_t, int);
static int mailbox_unix_undelete (mailbox_t, int);
/* updating/deleting */
static int mailbox_unix_is_deleted (mailbox_t, size_t msgno);
static int mailbox_unix_delete (mailbox_t, size_t msgno);
static int mailbox_unix_undelete (mailbox_t, size_t msgno);
static int mailbox_unix_expunge (mailbox_t);
static int mailbox_unix_is_deleted (mailbox_t, int);
static int mailbox_unix_is_updated (mailbox_t);
static int mailbox_unix_scan (mailbox_t, size_t *msgs);
/* appending */
static int mailbox_unix_new_msg (mailbox_t, int * id);
static int mailbox_unix_set_header (mailbox_t, int id, const char *h,
int offset, int n, int replace);
static int mailbox_unix_set_body (mailbox_t, int id, const char *b,
int offset, int n, int replace);
static int mailbox_unix_append (mailbox_t, int id);
static int mailbox_unix_destroy_msg (mailbox_t, int id);
static int mailbox_unix_new_msg (mailbox_t, size_t *msgno);
static int mailbox_unix_set_header (mailbox_t, size_t msgno, const char *h,
size_t len, int replace);
static int mailbox_unix_set_body (mailbox_t, size_t msgno, const char *b,
size_t len, int replace);
static int mailbox_unix_append (mailbox_t, size_t msgno);
static int mailbox_unix_destroy_msg (mailbox_t, size_t msgno);
/* reading */
static int mailbox_unix_get_body (mailbox_t, int id, char *b,
int offset, int n);
static int mailbox_unix_get_mbody (mailbox_t, int id, char **b,
int *n);
static int mailbox_unix_get_header (mailbox_t, int id, char *h,
int offset, int n);
static int mailbox_unix_get_mheader (mailbox_t, int id, char **h,
int *n);
static int mailbox_unix_get_body (mailbox_t, size_t msgno, off_t off,
char *b, size_t len, size_t *n);
static int mailbox_unix_get_header (mailbox_t, size_t msgno, off_t off,
char *h, size_t len, size_t *n);
static int mailbox_unix_get_size (mailbox_t, size_t msgno, size_t *header,
size_t *body);
/* setting flags */
static int mailbox_unix_is_read (mailbox_t, size_t msgno);
static int mailbox_unix_set_read (mailbox_t, size_t msgno);
static int mailbox_unix_is_seen (mailbox_t, size_t msgno);
static int mailbox_unix_set_seen (mailbox_t, size_t msgno);
/* owner and group
static int mailbox_unix_set_owner (mailbox_t mbox, uid_t uid);
static int mailbox_unix_get_owner (mailbox_t mbox, uid_t *uid);
static int mailbox_unix_set_group (mailbox_t mbox, gid_t gid);
static int mailbox_unix_get_group (mailbox_t mbox, gid_t *gid);
*/
/* locking */
static int mailbox_unix_lock (mailbox_t, int flag);
static int mailbox_unix_unlock (mailbox_t);
static int mailbox_unix_ilock (mailbox_t, int flag);
static int mailbox_unix_iunlock (mailbox_t);
/* miscellany */
static int mailbox_unix_scan (mailbox_t, int *msgs);
static int mailbox_unix_is_updated (mailbox_t);
static int mailbox_unix_get_timeout (mailbox_t, int *timeout);
static int mailbox_unix_set_timeout (mailbox_t, int timeout);
static int mailbox_unix_get_refresh (mailbox_t, int *refresh);
static int mailbox_unix_set_refresh (mailbox_t, int refresh);
static int mailbox_unix_get_size (mailbox_t, int id, size_t *size);
static int mailbox_unix_set_notification (mailbox_t,
int (*func) (mailbox_t, void *arg));
static int mailbox_unix_size (mailbox_t, off_t *size);
/* private stuff */
static int mailbox_unix_is_from (const char *);
static int mailbox_unix_readhdr (mailbox_t mbox, char *buf, size_t len,
off_t *content_length);
static int mailbox_unix_sigblock ();
static int mailbox_unix_sigunblock ();
/* Having a structure initialize at compiletime instead of runtime
may speed thing a bit, but it is a real pain to maintain with
the changing API */
static struct _mailbox unixmbox =
{
/* Data */
(char *)NULL, /* char *name ; */
(uid_t)-1, /* uid_t owner; */
(gid_t)-1, /* gid_t group; */
0, /* messages */
0, /* num_deleted */
(off_t)0, /* size */
0, /* lock */
0, /* timeout; */
0, /* refresh; */
(int (*)())NULL, /* (*func) __P ((mailbox_t, void *arg)) */
/* type of mailbox */
&_mailbox_unix_type, /*struct mailbox_type *mtype; */
/* back pointer to the specific mailbox */
(void *)NULL, /* void *data; */
/* Functions */
mailbox_unix_open, /* (*_open) */
mailbox_unix_close, /* (*_close) */
/* type */
mailbox_unix_get_name, /* (*_get_name) */
NULL, /* (*_get_mname) */
/* passwd if needed */
NULL, /* (*_get_passwd) */
NULL, /* (*_get_mpasswd) */
NULL, /* (*_set_passwd) */
/* updating/deleting mesgs */
mailbox_unix_is_deleted, /* (*_is_deleted) */
mailbox_unix_delete, /* (*_delete) */
mailbox_unix_undelete, /* (*_undelete) */
mailbox_unix_expunge, /* (*_expunge) */
mailbox_unix_is_updated, /* (*_is_updated) */
mailbox_unix_scan, /* (*_scan) */
/* appending messages */
mailbox_unix_new_msg, /* (*_new_msg) */
mailbox_unix_set_header, /* (*_set_header) */
mailbox_unix_set_body, /* (*_set_body) */
mailbox_unix_append, /* (*_append) */
mailbox_unix_destroy_msg, /* (*_destroy_msg) */
/* external locking */
mailbox_unix_lock, /* (*_lock) */
mailbox_unix_unlock, /* (*_unlock) */
/* internal locking */
mailbox_unix_ilock, /* (*_ilock) */
mailbox_unix_iunlock, /* (*_iunlock) */
/* reading mesgs */
mailbox_unix_get_body, /* (*_get_body) */
NULL, /* (*_get_mbody) */
mailbox_unix_get_header, /* (*_get_header) */
NULL, /* (*_get_mheader) */
mailbox_unix_get_size, /* (*_get_msg_size) */
/* setting flags */
mailbox_unix_is_read, /* (*_msg_is_read) */
mailbox_unix_set_read, /* (*_msg_set_read) */
mailbox_unix_is_seen, /* (*_msg_is_seen) */
mailbox_unix_set_seen, /* (*_msg_set_seen) */
/* owner and group */
NULL, /* (*_set_owner) */
NULL, /* (*_get_owner) */
NULL, /* (*_set_group) */
NULL, /* (*_get_group) */
mailbox_unix_size, /* (*_size) */
NULL, /* (*_get_timeout) */
NULL, /* (*_set_timeout) */
NULL, /* (*_get_refresh) */
NULL, /* (*_set_refresh) */
NULL, /* (*_set_notification) */
};
int
mailbox_unix_init (mailbox_t *pmbox, const char *name)
{
mailbox_t mbox;
size_t len;
mailbox_unix_data_t mud;
char *sep;
/*
Again should we do an open() and check if indeed this is a
correct mbox ? I think not, this should be delay to _open()
*/
/* sanity check */
if (name == NULL || *name == '\0')
{
return EINVAL;
}
/* allocate memory for mbox */
mbox = calloc (1, sizeof (*mbox));
if (mbox == NULL)
return -1; /* errno set by calloc() */
{
return ENOMEM; /* errno set by calloc() */
}
/* set the type */
mbox->mtype = &_mailbox_unix_type;
/* binary copy of the function */
*mbox = unixmbox;
mbox->_open = mailbox_unix_open;
mbox->_close = mailbox_unix_close;
/* specific unix mbox data */
mud = mbox->data = calloc (1, sizeof (*mud));
if (mbox->data == NULL)
{
mailbox_unix_destroy (&mbox);
return ENOMEM;
}
mbox->_get_name = mailbox_unix_get_name;
mbox->_get_mname = mailbox_unix_get_mname;
/* copy the name */
len = strlen (name) + 1;
mbox->name = calloc (len, sizeof (char));
if (mbox->name == NULL)
{
mailbox_unix_destroy (&mbox);
return ENOMEM;
}
memcpy (mbox->name, name, len);
/* passwd */
mbox->_get_passwd = mailbox_unix_get_passwd;
mbox->_get_mpasswd = mailbox_unix_get_mpasswd;
mbox->_set_passwd = mailbox_unix_set_passwd;
/* save the basename and dirname */
sep = strrchr (name, '/');
if (sep)
{
size_t baseln;
mud->dirname = calloc (sep - name + 1, sizeof (char));
if (mud->dirname == NULL)
{
mailbox_unix_destroy (&mbox);
return ENOMEM;
}
memcpy (mud->dirname, name, sep - name);
/* deleting */
mbox->_delete = mailbox_unix_delete;
mbox->_undelete = mailbox_unix_undelete;
mbox->_expunge = mailbox_unix_expunge;
mbox->_is_deleted = mailbox_unix_is_deleted;
baseln = strlen (++sep) + 1;
mud->basename = calloc (baseln, sizeof (char));
if (mud->basename == NULL)
{
mailbox_unix_destroy (&mbox);
return ENOMEM;
}
memcpy (mud->basename, sep, baseln);
}
else
{
mud->dirname = calloc (2 , sizeof (char));
if (mud->dirname == NULL)
{
mailbox_unix_destroy (&mbox);
return ENOMEM;
}
mud->dirname[0] = '.';
/* appending */
mbox->_new_msg = mailbox_unix_new_msg;
mbox->_set_header = mailbox_unix_set_header;
mbox->_set_body = mailbox_unix_set_body;
mbox->_append = mailbox_unix_append;
mbox->_destry_msg = mailbox_unix_destroy_msg;
mud->basename = calloc (len, sizeof (char));
if (mud->basename == NULL)
{
mailbox_unix_destroy (&mbox);
return ENOMEM;
}
memcpy (mud->basename, name, len);
}
/* reading */
mbox->_get_body = mailbox_unix_get_body;
mbox->_get_mbody = mailbox_unix_get_mbody;
mbox->_get_header = mailbox_unix_get_header;
mbox->_get_mheader = mailbox_unix_get_mheader;
/* mutex when accessing the structure fields */
/* FIXME: should we use rdwr locks instead ?? */
#ifdef HAVE_PHTREAD_H
pthread_mutex_init (mud->mutex, NULL);
#endif
/* locking */
mbox->_lock = mailbox_unix_lock;
mbox->_unlock = mailbox_unix_unlock;
/* miscellany */
mbox->_scan = mailbox_unix_scan;
mbox->_is_updated = mailbox_unix_is_updated;
mbox->_get_timeout = mailbox_unix_get_timeout;
mbox->_set_timeout = mailbox_unix_set_timeout;
mbox->_get_refresh = mailbox_unix_get_refresh;
mbox->_set_refresh = mailbox_unix_set_refresh;
mbox->_get_size = mailbox_unix_get_size;
mbox->_set_notification = mailbox_unix_set_notification;
(*pmbox) = mbox;
return 0;
return 0; /* okdoke */
}
void
mailbox_unix_destroy (mailbox_t *mbox)
mailbox_unix_destroy (mailbox_t *pmbox)
{
return;
if (pmbox && *pmbox)
{
mailbox_t mbox = *pmbox;
mailbox_unix_close (mbox);
if (mbox->data)
{
mailbox_unix_data_t mud = mbox->data;
if (mud->dirname)
free (mud->dirname);
if (mud->basename)
free (mud->basename);
if (mud->messages)
free (mud->messages);
free (mbox->data);
}
if (mbox->name)
free (mbox->name);
free (*pmbox);
pmbox = NULL;
}
}
/* start of Mbox Implementation */
static int mailbox_unix_open (mailbox_t mbox, int flags)
static int
mailbox_unix_open (mailbox_t mbox, int flags)
{
mailbox_unix_data_t mud = mbox->data;
int fd = -1;
int flg = 0;
char * mode;
/*
FIXME: This is another problem, should we have a special set of flags
MU_MB_{CREAT,APPEND,RDONLY,RDWR} or use the default open(2)
and if RDONLY, should we have some security checks ?
*/
if (flags & MU_MB_WRONLY)
{
flg = O_WRONLY;
}
else if (flags & MU_MB_RDWR)
{
flg = O_RDWR;
}
else /* default */
{
flg = O_RDONLY;
}
if (flags & MU_MB_APPEND)
{
flg |= O_APPEND;
}
/* handle CREAT with care, not to follow symlinks */
if (flags & MU_MB_CREAT)
{
/* firts see if the file already exists */
fd = open(mbox->name, flg);
if (fd == -1)
{
/* oops bail out */
if (errno != ENOENT)
{
return errno;
}
/* Create the file */
fd = open(mbox->name, flg|O_CREAT|O_EXCL, 0600);
if (fd < 0)
{
return errno;
}
}
/*
FIXME: How about owner(uid), to whom we set it to ?
do We need a _set_owner(uid) to mailbox_t
*/
(void)fchown (fd, mbox->owner, mbox->group);
/* FIXME: should we have a mode field ? */
(void)fchmod (fd, 0600);
}
else
{
fd = open (mbox->name, flg);
if (fd < 0)
{
return errno;
}
}
/* we use FILE * object */
if (flg & MU_MB_RDWR)
{
mode = "r+";
}
else if (flg & MU_MB_WRONLY)
{
mode = "w";
}
else if (flg & MU_MB_APPEND)
{
mode = "a";
}
else /* default readonly*/
{
mode = "r";
}
/* clean up */
mailbox_unix_close (mbox);
mailbox_unix_ilock (mbox, MU_MB_WRLOCK);
{
mud->file = fdopen (fd, mode);
if (mud->file == NULL)
{
/* what's up ?? */
mailbox_unix_iunlock (mbox);
return ENOMEM;
}
flockfile (mud->file);
{
char buf [BUFSIZ];
if (fgets (buf, sizeof (buf), mud->file) == NULL)
{
if (feof (mud->file))
{
clearerr (mud->file); /* the file maybe empty */
}
else if (ferror (mud->file))
{
mailbox_unix_iunlock (mbox);
return EIO;
}
}
else
{
if (strncmp ("From ", buf, 5) != 0)
{
/* not a Unix mbox */
fclose (mud->file);
mailbox_unix_iunlock (mbox);
return EIO;
}
else
{
rewind (mud->file);
}
}
}
funlockfile (mud->file);
}
mailbox_unix_iunlock (mbox);
return 0;
}
static int
mailbox_unix_close (mailbox_t mbox)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t)mbox->data;
mailbox_unix_ilock (mbox, MU_MB_WRLOCK);
{
/* make sure we do not hold any lock for that file */
mailbox_unix_unlock (mbox);
if (mud->file)
{
fclose (mud->file);
}
mud->file = NULL;
}
mailbox_unix_iunlock (mbox);
return 0;
}
static int
mailbox_unix_get_name (mailbox_t mbox, int *id, char *name,
size_t len, size_t *n)
{
char *s = _mailbox_unix_type.name;
size_t i = strlen (s);
if (id)
{
*id = _mailbox_unix_type.id;
}
if (name && len > 0)
{
i = (len < i) ? len : i;
strncpy (name, s, i - 1);
name [i - 1] = 0;
}
if (n)
{
*n = i;
}
return 0;
}
/* passwd */
/* We don't care */
/* FIXME: a little weak, we should do full reconnaissance of the
the "From " header :
From email weekday month day time timezone year
*/
static int
mailbox_unix_is_from (const char *from)
{
const char *sep;
return (strncmp (from, "From ", 5) == 0
&& (sep = strchr (from, ':')) != NULL
&& strchr (sep, ':') != NULL);
}
static int
mailbox_unix_readhdr (mailbox_t mbox, char *buf, size_t len,
off_t *content_length)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t)mbox->data;
mailbox_unix_msg_t mum = mud->messages;
char *sep;
size_t count = mbox->messages;
/* skip over the remaining header */
while (fgets (buf, len, mud->file))
{
/* FIXME: The heuristic is still weak
we will break and consider things not to be a header if:
1: an empty line
2: can not be a header
*/
if (strcmp (buf, "\n") == 0 || strcmp (buf, "\r\n") == 0
|| (isalpha (buf[0]) && (sep = strchr (buf, ':')) == NULL))
{
break;
}
/* get the the Content lenght of the body if possible */
if (strncmp (buf, "Content-Length:", 15) == 0)
{
sep = strchr(buf, ':'); /* pass the ':' */
sep[strlen (sep) - 1] = '\0'; /* chop the newline */
*content_length = strtol (sep + 1, NULL, 10);
}
if (strncmp (buf, "Status:", 7) == 0)
{
sep = strchr(buf, ':'); /* pass the ':' */
if (strchr (sep, 'R') != NULL)
{
mum[count - 1].is_read = 1;
}
if (strchr (sep, 'O') != NULL)
{
mum[count - 1].is_seen = 1;
}
}
}
if (feof (mud->file) || ferror (mud->file))
{
return EIO;
}
return 0;
}
/* Updating/deleting */
static int
mailbox_unix_scan (mailbox_t mbox, size_t *msgs)
{
char buf[BUFSIZ];
int header = 1;
int body = 0;
off_t content_length = -1;
size_t count = 0;
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
mailbox_unix_msg_t mum;
struct stat st;
mailbox_unix_ilock (mbox, MU_MB_WRLOCK);
/* FIXME: I should also block signals since
We can affor to be intr */
flockfile (mud->file);
rewind (mud->file);
if (fstat (fileno (mud->file), &st) != 0)
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
return EIO;
}
mud->mtime = st.st_mtime;
mud->size = st.st_size;
while (fgets (buf, sizeof (buf), mud->file))
{
/* header */
if ((header && mailbox_unix_is_from (buf)))
{
/* FIXME: What happen if some mailer violates the rfc8222 and the
"From " field contains a NULL byte */
int over = strlen (buf);
count++;
if (count > mbox->messages)
{
mum = realloc (mud->messages, count * sizeof (*mum));
if (mum == NULL)
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
return ENOMEM;
}
mbox->messages++;
memset (&mum[count - 1], 0, sizeof (*mum));
}
mud->messages = mum;
mum[count - 1].header = ftell (mud->file);
mum[count - 1].header -= over;
/* skip over the remaining header */
if (mailbox_unix_readhdr (mbox, buf, sizeof (buf),
&content_length) != 0)
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
return EIO;
}
header = 0;
body = !header;
} /* header */
/* body */
if (body && content_length >= 0)
{
/* ouf ! we got the size */
mum[count - 1].body = ftell (mud->file) - strlen (buf);
fseek (mud->file, content_length, SEEK_CUR);
mum[count - 1].end = ftell (mud->file);
content_length = -1;
header = 1;
body = !header;
}
else if (body)
{
/* oops! some heuristic since we do not know the size of the body */
if (mum[count - 1].body == 0)
{
mum[count - 1].body = ftell (mud->file) - strlen (buf);
}
if (mailbox_unix_is_from (buf))
{
int over = strlen (buf);
mum[count - 1].end = ftell (mud->file);
mum[count - 1].end -= over;
count++;
if (count > mbox->messages)
{
mum = realloc (mud->messages, count * sizeof (*mum));
if (mum == NULL)
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
return ENOMEM;
}
mbox->messages++;
memset (&mum[count - 1], 0, sizeof (*mum));
}
mud->messages = mum;
mum[count - 1].header = ftell (mud->file);
mum[count - 1].header -= over;
/* skip over the remaining header */
if (mailbox_unix_readhdr (mbox, buf, sizeof (buf),
&content_length) != 0)
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
return EIO;
}
mum[count - 1].body = ftell (mud->file) - strlen (buf);
if (content_length >= 0)
{
fseek (mud->file, content_length, SEEK_CUR);
mum[count - 1].end = ftell (mud->file);
content_length = -1;
header = 0;
body = !header;
}
}
} /* body */
} /* while */
mum[count - 1].end = ftell (mud->file);
if (feof (mud->file))
{
clearerr (mud->file);
}
else if (ferror (mud->file))
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
return EIO;
}
rewind (mud->file);
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
if (msgs)
*msgs = count;
return 0;
}
static int
mailbox_unix_is_updated (mailbox_t mbox)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
struct stat st;
if (mud == 0 || fstat (fileno (mud->file), &st) < 0)
{
return 0;
}
return (mud->mtime == st.st_mtime);
}
static int
mailbox_unix_is_valid (mailbox_t mbox, size_t msgno)
{
/* valid ? */
return (mbox->messages > 0 && msgno <= mbox->messages);
}
static int
mailbox_unix_is_deleted (mailbox_t mbox, size_t msgno)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
/* Do we have a consistent view of the mbox ? */
if (mud == NULL || ! mailbox_unix_is_valid (mbox, msgno))
{
return 0;
}
return mud->messages[msgno].deleted;
}
static int
mailbox_unix_delete (mailbox_t mbox, size_t msgno)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
/* oops out of range ? */
/* if already deleted, noop */
if (mud == NULL || ! mailbox_unix_is_valid (mbox, msgno)
|| mailbox_unix_is_deleted (mbox, msgno))
{
return 0;
}
/* Mark for deletion */
mud->messages[msgno].deleted = 1;
mbox->num_deleted++;
return 0;
}
static int
mailbox_unix_undelete (mailbox_t mbox, size_t msgno)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
/* oops out of range ? */
/* if already undeleted, noop */
if (mud == 0 || ! mailbox_unix_is_valid (mbox, msgno)
|| ! mailbox_unix_is_deleted (mbox, msgno))
{
return 0;
}
/* Mark undeletion */
mud->messages[msgno].deleted = 0;
mbox->num_deleted--;
return 0;
}
static FILE *
mailbox_unix_tmpfile ()
{
/*FIXME: racing conidtions, to correct, .i.e don;t use tmpfile*/
//return tmpfile ();
return fopen ("/tmp/mymail", "w");
}
/*
FIXME: the use of tmpfile() on some system can lead to
race condition, We should use a safer approach.
We take a very naive approach to this, it involves unfortunately
two copies.
*/
static int
mailbox_unix_expunge (mailbox_t mbox)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t)mbox->data;
mailbox_unix_msg_t mum;
sigset_t sigset;
FILE *tmpfile;
size_t i;
off_t total = 0;
char buffer [BUFSIZ];
if (mud == NULL)
{
return EINVAL;
}
if (mbox->messages == 0 || mbox->num_deleted <= 0)
{
/* noop */
return 0;
}
tmpfile = mailbox_unix_tmpfile ();
if (tmpfile == NULL)
{
return errno;
}
/* Get the lock */
mailbox_unix_ilock (mbox, MU_MB_RDLOCK);
flockfile (mud->file);
if (mailbox_unix_lock (mbox, MU_MB_WRLOCK) < 0)
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
fclose (tmpfile);
return EINVAL;
}
/* Do we have a consistent view of the mbox */
if (! mailbox_unix_is_updated (mbox))
{
/* things change, flag an error */
mailbox_unix_unlock (mbox);
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
fclose (tmpfile);
return EAGAIN;
}
rewind (mud->file);
/* copy to temp file emails not mark deleted emails */
for (i = 1; i <= mbox->messages; i++)
{
mum = &mud->messages[i];
if ( ! mum->deleted)
{
size_t len = mum->body - mum->header;
size_t nread;
/* copy the header */
if (fseek (mud->file, mum->header, SEEK_SET) == -1)
{
mailbox_unix_unlock (mbox);
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
fclose (tmpfile);
return EIO;
}
while (len > 0)
{
nread = (len < sizeof (buffer)) ? len : sizeof (buffer);
if (fread (buffer, sizeof (*buffer), nread, mud->file) != nread
|| fwrite(buffer, sizeof(*buffer), nread, tmpfile) != nread)
{
mailbox_unix_unlock (mbox);
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
fclose (tmpfile);
return EIO;
}
len -= nread;
total += nread;
}
/* FIXME: We should set the seen flag also here */
/* copy the body */
len = mum->end - mum->body;
if (fseek (mud->file, mum->body, SEEK_SET) < 0)
{
mailbox_unix_unlock (mbox);
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
fclose (tmpfile);
return EIO;
}
while (len > 0)
{
nread = (len < sizeof (buffer)) ? len : sizeof (buffer);
if (fread (buffer, sizeof (*buffer), nread, mud->file) != nread
|| fwrite(buffer, sizeof(*buffer), nread, tmpfile) != nread)
{
mailbox_unix_unlock (mbox);
fclose (tmpfile);
mailbox_unix_iunlock (mbox);
funlockfile (mud->file);
return EIO;
}
len -= nread;
total += nread;
}
}
}
/* Critical section, we can not allowed signal here */
sigemptyset (&sigset);
sigaddset (&sigset, SIGTERM);
sigaddset (&sigset, SIGHUP);
sigaddset (&sigset, SIGTSTP);
sigaddset (&sigset, SIGINT);
sigaddset (&sigset, SIGWINCH);
sigprocmask (SIG_BLOCK, &sigset, 0);
/* truncate the mailbox and rewrite it */
rewind (mud->file);
rewind (tmpfile);
if (ftruncate (fileno(mud->file), total) < 0)
{
mailbox_unix_unlock (mbox);
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
fclose (tmpfile);
sigprocmask (SIG_UNBLOCK, &sigset, 0);
return EIO;
}
while (total > 0)
{
size_t nread = ((unsigned)total < sizeof (buffer)) ? total : sizeof (buffer);
if (fread (buffer, sizeof (*buffer), nread, mud->file) != nread
|| fwrite (buffer, sizeof (*buffer), nread, tmpfile) != nread)
{
mailbox_unix_unlock (mbox);
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
fclose (tmpfile);
sigprocmask (SIG_UNBLOCK, &sigset, 0);
return EIO;
}
total -= nread;
}
fflush (mud->file);
/* Release the lock */
mailbox_unix_unlock (mbox);
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
fclose (tmpfile);
sigprocmask (SIG_UNBLOCK, &sigset, 0);
return 0;
}
/* appending */
static int
mailbox_unix_new_msg (mailbox_t mbox, size_t *msgno)
{
return ENOSYS;
}
static int
mailbox_unix_set_header (mailbox_t mbox, size_t msgno, const char *h,
size_t len, int replace)
{
return ENOSYS;
}
static int
mailbox_unix_set_body (mailbox_t mbox, size_t msgno, const char *b,
size_t len, int replace)
{
return ENOSYS;
}
static int
mailbox_unix_append (mailbox_t mbox, size_t msgno)
{
return ENOSYS;
}
static int
mailbox_unix_destroy_msg (mailbox_t mbox, size_t msgno)
{
return ENOSYS;
}
/* reading */
static int
mailbox_unix_get_body (mailbox_t mbox, size_t msgno, off_t off,
char *buffer, size_t len, size_t *n)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
size_t nread;
/* check if valid */
if (len < 1 || mud == NULL || ! mailbox_unix_is_valid (mbox, msgno))
{
return EINVAL;
}
mailbox_unix_ilock (mbox, MU_MB_RDLOCK);
flockfile (mud->file);
{
mailbox_unix_msg_t mum = &(mud->messages[msgno]);
off_t ln = mum->end - mum->body + off;
if (ln < 0)
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
return EIO;
}
nread = (ln < len) ? ln : len;
/* position the file pointer and the buffer */
if (fseek (mud->file, mum->body + off, SEEK_SET) < 0)
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
return EIO;
}
if (fread (buffer, sizeof (*buffer), nread, mud->file) != nread)
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
return EIO;
}
buffer[nread - 1] = '\0';
}
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
if (n)
*n = nread;
return 0;
}
static int
mailbox_unix_get_header (mailbox_t mbox, size_t msgno, off_t off,
char *buffer, size_t len, size_t *n)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
size_t nread = 0;
/* check if valid */
if ( len < 1 || mud == NULL || ! mailbox_unix_is_valid (mbox, msgno))
{
return EINVAL;
}
mailbox_unix_ilock (mbox, MU_MB_RDLOCK);
flockfile (mud->file);
{
mailbox_unix_msg_t mum = &(mud->messages[msgno]);
off_t ln = mum->body - mum->header + off;
if (ln < 0)
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
return EIO;
}
nread = (ln < len) ? ln : len;
/* position the file pointer and the buffer */
if (fseek (mud->file, mum->header + off, SEEK_SET) < 0)
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
return EIO;
}
if (fread (buffer, sizeof (*buffer), nread, mud->file) != nread)
{
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
return EIO;
}
buffer[nread - 1] = '\0';
}
funlockfile (mud->file);
mailbox_unix_iunlock (mbox);
if (n)
*n = nread;
return 0;
}
/* setting flags */
static int
mailbox_unix_is_read (mailbox_t mbox, size_t msgno)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
if (mud == 0 || ! mailbox_unix_is_valid (mbox, msgno))
{
return 0;
}
return mud->messages[msgno].is_read;
}
static int
mailbox_unix_set_read (mailbox_t mbox, size_t msgno)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
if (mud == 0 || ! mailbox_unix_is_valid (mbox, msgno))
{
return EINVAL;
}
mud->messages[msgno].is_read = 1;;
return 0;
}
static int
mailbox_unix_is_seen (mailbox_t mbox, size_t msgno)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
if (mud == 0 || ! mailbox_unix_is_valid (mbox, msgno))
{
return 0;
}
return mud->messages[msgno].is_seen;
}
static int
mailbox_unix_set_seen (mailbox_t mbox, size_t msgno)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
if (mud == 0 || ! mailbox_unix_is_valid (mbox, msgno))
{
return EINVAL;
}
mud->messages[msgno].is_seen = 1;
return 0;
}
/* locking */
static int
mailbox_unix_ilock (mailbox_t mbox, int flag)
{
#ifdef HAVE_PTHREAD_H
pthread_mutex_lock (&mutex)
#endif
return 0;
}
static int
mailbox_unix_iunlock (mailbox_t mbox)
{
#ifdef HAVE_PTHREAD_H
pthread_mutex_unlock (&mutex)
#endif
return 0;
}
static int
mailbox_unix_lock (mailbox_t mbox, int flag)
{
#ifdef HAVE_MAILOCK_H
#endif
return 0;
}
static int
mailbox_unix_unlock (mailbox_t mbox)
{
#ifdef HAVE_MAILOCK_H
#endif
return 0;
}
/* miscellany */
static int
mailbox_unix_size (mailbox_t mbox, off_t *size)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
struct stat st;
int fd;
if (mud == NULL || mud->file == NULL)
{
/* maybe was not open yet ?? */
return EIO;
}
fd = fileno (mud->file);
if (fstat (fd, &st) != 0)
{
/* oops !! */
/* errno set by fstat () */
return EIO;
}
*size = st.st_size;
return 0;
}
static int
mailbox_unix_get_size (mailbox_t mbox, size_t msgno, size_t *h, size_t *b)
{
mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data;
mailbox_unix_msg_t mum;
if (mailbox_unix_is_valid (mbox, msgno))
{
return EINVAL;
}
mum = &(mud->messages[msgno]);
if (h)
*h = mum->header - mum->body;
if (b)
*b = mum->body - mum->header;
return 0;
}
......