Commit 193c1ef7 193c1ef73dcbc058ee4481e2eed90288ffa5db24 by Alain Magloire

attribute.c attribute.h attribute0.h header.c header.h

 	header0.h mailbox.c mailbox.h mailbox0.h mbx_mbox.c mbx_unix.c
 	message.c registrar.c registrar.h registrar0.h rfc822.c url.c

more cleanups.
1 parent e3fa2e8c
......@@ -62,7 +62,6 @@ attribute_set_answered (attribute_t attr)
if (attr == NULL)
return EINVAL;
attr->flag|= MU_ATTRIBUTE_ANSWERED;
attr->flag |= MU_ATTRIBUTE_SEEN;
return 0;
}
......@@ -72,7 +71,6 @@ attribute_set_flagged (attribute_t attr)
if (attr == NULL)
return EINVAL;
attr->flag |= MU_ATTRIBUTE_FLAGGED;
attr->flag |= MU_ATTRIBUTE_SEEN;
return 0;
}
......@@ -82,7 +80,6 @@ attribute_set_read (attribute_t attr)
if (attr == NULL)
return EINVAL;
attr->flag |= MU_ATTRIBUTE_READ;
attr->flag |= MU_ATTRIBUTE_SEEN;
return 0;
}
......@@ -175,9 +172,6 @@ attribute_unset_seen (attribute_t attr)
if (attr == NULL)
return 0;
attr->flag ^= MU_ATTRIBUTE_SEEN;
attr->flag ^= MU_ATTRIBUTE_ANSWERED;
attr->flag ^= MU_ATTRIBUTE_FLAGGED;
attr->flag ^= MU_ATTRIBUTE_READ;
return 0;
}
......@@ -235,3 +229,38 @@ attribute_unset_recent (attribute_t attr)
return 0;
}
int
attribute_is_equal (attribute_t attr, attribute_t attr2)
{
if (attr == NULL || attr2 == NULL)
return 0;
return attr->flag == attr2->flag;
}
int
attribute_copy (attribute_t dest, attribute_t src)
{
if (dest == NULL || src == NULL)
return EINVAL;
memcpy (dest, src, sizeof (*dest));
return 0;
}
int
attribute_set_owner (attribute_t attr, message_t *msg)
{
if (attr == NULL)
return EINVAL;
attr->message = msg;
return 0;
}
int
attribute_get_owner (attribute_t attr, message_t *msg)
{
if (attr == NULL)
return EINVAL;
if (msg)
*msg = attr->message;
return 0;
}
......
......@@ -60,6 +60,8 @@ extern int attribute_unset_draft __P ((attribute_t));
extern int attribute_unset_recent __P ((attribute_t));
extern int attribute_unset_read __P ((attribute_t));
extern int attribute_is_equal __P ((attribute_t att1, attribute_t att2));
#ifdef __cplusplus
}
#endif
......
......@@ -18,6 +18,7 @@
#ifndef _ATTRIBUTE0_H
#define _ATTRIBUTE0_H
#include <message.h>
#include <attribute.h>
#include <sys/types.h>
......@@ -48,6 +49,11 @@ struct _attribute
void *message;
};
/* not user visible ?? */
extern int attribute_copy __P ((attribute_t dst, attribute_t src));
extern int attribute_set_owner __P ((attribute_t attr, message_t *msg));
extern int attribute_get_owner __P ((attribute_t attr, message_t *msg));
#ifdef __cplusplus
}
#endif
......
......@@ -45,7 +45,7 @@ int
header_set_value (header_t h, const char *fn, const char *fb, size_t n,
int replace)
{
if (h == NULL)
if (h == NULL || h->_set_value == NULL)
return EINVAL;
return h->_set_value (h, fn, fb, n, replace);
}
......@@ -54,15 +54,41 @@ int
header_get_value (header_t h, const char *fn, char *fb,
size_t len, size_t *n)
{
if (h == NULL)
if (h == NULL || h->_get_value == NULL )
return EINVAL;
return h->_get_value (h, fn, fb, len, n);
}
int
header_entry_name (header_t h, size_t num, char *buf, size_t len, size_t *n)
{
if (h == NULL || h->_entry_name == NULL)
return EINVAL;
return h->_entry_name (h, num, buf, len, n);
}
int
header_entry_value (header_t h, size_t num, char *buf, size_t len, size_t *n)
{
if (h == NULL || h->_entry_value == NULL)
return EINVAL;
return h->_entry_value (h, num, buf, len, n);
}
int
header_entry_count (header_t h, size_t *num)
{
if (h == NULL || h->_entry_count)
return EINVAL;
return h->_entry_count (h, num);
}
ssize_t
header_get_data (header_t h, char *data, size_t len, off_t off, int *err)
{
if (h == NULL)
if (h == NULL || h->_get_data)
return EINVAL;
return h->_get_data (h, data, len, off, err);
}
......
......@@ -74,9 +74,12 @@ extern void header_destroy __P ((header_t *));
extern int header_set_value __P ((header_t, const char *fn,
const char *fv, size_t n, int replace));
extern int header_get_value __P ((header_t, const char *fn, char *fv,
size_t len, size_t *n));
extern ssize_t header_get_data __P ((header_t h, char *data,
size_t len, off_t off, int *err));
size_t len, size_t *nwritten));
extern int header_entry_count __P ((header_t, size_t *num));
extern int header_entry_name __P ((header_t, size_t num, char *buf,
size_t buflen, size_t *total));
extern int header_entry_value __P ((header_t, size_t num, char *buf,
size_t buflen, size_t *total));
#ifdef _cpluscplus
}
#endif
......
......@@ -44,6 +44,7 @@ typedef struct _hdr *hdr_t;
struct _header
{
size_t num;
/* Data */
void *data;
/* owner ? */
......@@ -56,13 +57,23 @@ struct _header
size_t n, int replace));
int (*_get_value) __P ((header_t, const char *fn, char *fv,
size_t len, size_t *n));
ssize_t (*_get_data) __P ((header_t h, char *data,
size_t len, off_t off, int *err));
int (*_entry_count) __P ((header_t, size_t *));
int (*_entry_name) __P ((header_t, size_t num, char *buf,
size_t buflen, size_t *nwritten));
int (*_entry_value) __P ((header_t, size_t num, char *buf,
size_t buflen, size_t *nwritten));
ssize_t (*_get_data) __P ((header_t h, char *data, size_t len,
off_t off, int *err));
int (*_parse) __P ((header_t, const char *blurb, size_t len));
} ;
};
extern ssize_t header_get_data __P ((header_t h, char *data,
size_t len, off_t off, int *err));
/* rfc822 */
extern int rfc822_init __P ((header_t *ph, const char *blurb, size_t len));
extern void rfc822_destroy __P ((header_t *ph));
#ifdef _cpluscplus
}
#endif
......
......@@ -61,11 +61,7 @@ mailbox_init (mailbox_t *pmbox, const char *name, int id)
/* if things went ok set mreg for mailbox_destroy and the URL */
if (status == 0)
{
(*pmbox)->url = url;
(*pmbox)->_init = mreg->_init;
(*pmbox)->_destroy = mreg->_destroy;
}
return status;
}
......@@ -245,10 +241,26 @@ mailbox_set_auth (mailbox_t mbox, auth_t auth)
}
int
mailbox_get_auth (mailbox_t mbox, auth_t *auth)
mailbox_get_auth (mailbox_t mbox, auth_t *pauth)
{
if (mbox == NULL || auth == NULL)
if (mbox == NULL || pauth == NULL)
return EINVAL;
*auth = mbox->auth;
*pauth = mbox->auth;
return 0;
}
int
mailbox_get_attribute (mailbox_t mbox, size_t msgno, attribute_t *pattr)
{
if (mbox == NULL || mbox->_get_attribute == NULL)
return ENOSYS;
return mbox->_get_attribute (mbox, msgno, pattr);
}
int
mailbox_set_attribute (mailbox_t mbox, size_t msgno, attribute_t attr)
{
if (mbox == NULL || mbox->_set_attribute == NULL)
return ENOSYS;
return mbox->_set_attribute (mbox, msgno, attr);
}
......
......@@ -22,6 +22,7 @@
#include <url.h>
#include <message.h>
#include <attribute.h>
#include <auth.h>
#include <locker.h>
......
......@@ -85,6 +85,10 @@ struct _mailbox
size_t len, off_t off, int *err));
ssize_t (*_get_body) __P ((mailbox_t, size_t msgno, char *b,
size_t len, off_t off, int *err));
int (*_get_attribute) __P ((mailbox_t mbox, size_t msgno,
attribute_t *attr));
int (*_set_attribute) __P ((mailbox_t mbox, size_t msgno,
attribute_t attr));
};
/* private */
......@@ -103,6 +107,10 @@ extern int mailbox_get_auth __P ((mailbox_t mbox, auth_t *auth));
extern int mailbox_set_auth __P ((mailbox_t mbox, auth_t auth));
extern int mailbox_get_locker __P ((mailbox_t mbox, locker_t *locker));
extern int mailbox_set_locker __P ((mailbox_t mbox, locker_t locker));
extern int mailbox_get_attribute __P ((mailbox_t mbox, size_t msgno,
attribute_t *attr));
extern int mailbox_set_attribute __P ((mailbox_t mbox, size_t msgno,
attribute_t attr));
extern int mailbox_progress __P ((mailbox_t mbox,
int (*progress) (int, void *arg),
void *arg));
......
......@@ -32,32 +32,41 @@ struct mailbox_registrar _mailbox_mbox_registrar =
};
/*
if there is no specific URL for file mailbox,
file://<path_name>
Caveat there is no specific URL for file mailbox or simple path name,
<path_name>
file:<path_name>
It would be preferrable to use :
maildir://<path>
unix://<path>
mmdf://<path>
maildir:<path>
unix:<path>
mmdf:<path>
This would eliminate heuristic discovery that would turn
out to be wrong. Caveat, there is no std URL for those
mailbox.
out to be wrong.
*/
static int
mailbox_mbox_init (mailbox_t *mbox, const char *name)
{
struct stat st;
char *scheme = strstr (name, "://");
size_t len;
if (scheme)
if (name == NULL || mbox == NULL)
return EINVAL;
len = strlen (name);
if (len >= 5 &&
(name[0] == 'f' || name[0] == 'F') &&
(name[1] == 'i' || name[1] == 'I') &&
(name[2] == 'l' || name[2] == 'L') &&
(name[3] == 'e' || name[3] == 'E') &&
name[4] == ':')
{
scheme += 3;
name = scheme;
name += 5;
}
/*
If they want to creat ?? should they know the type ???
What is the best course of action ??
* If they want to creat ?? should they know the type ???
* What is the best course of action ??
* For the default is unix if the file does not exist.
*/
if (stat (name, &st) < 0)
return _mailbox_unix_registrar._init (mbox, name);
......@@ -99,7 +108,7 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name)
{
if (strncmp (head, "From ", 5) == 0)
{
/* This is Unix Mbox */
/* This is a Unix Mbox */
close (fd);
return _mailbox_unix_registrar._init (mbox, name);
}
......
......@@ -183,12 +183,37 @@ message_size (message_t msg, size_t *size)
size_t hs, bs;
int status;
status = mailbox_get_size (msg->mailbox, msg->num, &hs, &bs);
if (status == 0)
{
if (size)
if (status != 0)
return status;
*size = hs + bs;
return 0;
}
return ENOSYS;
}
int
message_get_attribute (message_t msg, attribute_t *pattribute)
{
if (msg == NULL || pattribute == NULL)
return EINVAL;
if (msg->attribute)
*pattribute = msg->attribute;
if (msg->mailbox)
{
int status;
status = mailbox_get_attribute (msg->mailbox, msg->num, pattribute);
if (status != 0)
return status;
msg->attribute = *pattribute;
(*pattribute)->message = msg;
return 0;
}
return ENOSYS;
}
int
message_set_attribute (message_t msg, attribute_t attribute)
{
(void)msg; (void)attribute;
return ENOSYS;
}
......
......@@ -33,11 +33,12 @@
static struct _registrar registrar [] = {
{ NULL, NULL, 0, &registrar[1] }, /* sentinel, head list */
{ &_url_mbox_registrar, &_mailbox_mbox_registrar, 0, &registrar[2] },
{ &_url_unix_registrar, &_mailbox_unix_registrar, 0, &registrar[3] },
{ &_url_maildir_registrar, &_mailbox_maildir_registrar, 0, &registrar[4] },
{ &_url_mmdf_registrar, &_mailbox_mmdf_registrar, 0, &registrar[5] },
{ &_url_pop_registrar, &_mailbox_pop_registrar, 0, &registrar[6] },
{ &_url_file_registrar, &_mailbox_mbox_registrar, 0, &registrar[2] },
{ &_url_mbox_registrar, &_mailbox_mbox_registrar, 0, &registrar[3] },
{ &_url_unix_registrar, &_mailbox_unix_registrar, 0, &registrar[4] },
{ &_url_maildir_registrar, &_mailbox_maildir_registrar, 0, &registrar[5] },
{ &_url_mmdf_registrar, &_mailbox_mmdf_registrar, 0, &registrar[6] },
{ &_url_pop_registrar, &_mailbox_pop_registrar, 0, &registrar[7] },
{ &_url_imap_registrar, &_mailbox_imap_registrar, 0, &registrar[0] },
};
......@@ -175,6 +176,43 @@ registrar_get (int id,
}
int
registrar_entry_count (size_t *num)
{
struct _registrar *current;
size_t count;
for (count = 0, current = registrar->next; current != registrar;
current = current->next, count++)
;
if (num)
*num = count;
return 0;
}
int
registrar_entry (size_t num, struct url_registrar **ureg,
struct mailbox_registrar **mreg, int *id)
{
struct _registrar *current;
size_t count, status;
for (status = ENOENT, count = 0, current = registrar->next;
current != registrar; current = current->next, count++)
{
if (num == count)
{
if (ureg)
*ureg = current->ureg;
if (mreg)
*mreg = current->mreg;
if (id)
*id = (int)current;
status = 0;
break;
}
}
return status;
}
int
registrar_list (struct url_registrar **ureg, struct mailbox_registrar **mreg,
int *id, registrar_t *reg)
{
......
......@@ -59,6 +59,10 @@ extern int registrar_add __P ((struct url_registrar *ureg,
extern int registrar_remove __P ((int id));
extern int registrar_get __P ((int id, struct url_registrar **ureg,
struct mailbox_registrar **mreg));
extern int registrar_num __P ((size_t *num));
extern int registrar_get_entry __P ((size_t num, struct url_registrar **ureg,
struct mailbox_registrar **mreg,
int *id));
extern int registrar_list __P ((struct url_registrar **ureg,
struct mailbox_registrar **mreg,
int *id, registrar_t *reg));
......
......@@ -46,10 +46,21 @@ struct _registrar
struct _registrar *next;
};
/* This is function is obsolete use the registrar_entry_*() ones */
extern int registrar_list __P ((struct url_registrar **ureg,
struct mailbox_registrar **mreg,
int *id, registrar_t *reg));
extern int registrar_entry_count __P ((size_t *num));
extern int registrar_entry __P ((size_t num, struct url_registrar **ureg,
struct mailbox_registrar **mreg,
int *id));
/* IMAP */
extern struct mailbox_registrar _mailbox_imap_registrar;
extern struct url_registrar _url_imap_registrar;
/* FILE */
extern struct url_registrar _url_file_registrar;
/* MBOX */
extern struct mailbox_registrar _mailbox_mbox_registrar;
extern struct url_registrar _url_mbox_registrar;
......
......@@ -28,10 +28,15 @@
static int rfc822_parse (header_t h, const char *blurb, size_t len);
static int rfc822_set_value (header_t h, const char *fn, const char *fb,
size_t n, int replace);
ssize_t rfc822_get_data (header_t h, char *buf, size_t buflen,
static int rfc822_get_value (header_t h, const char *fn, char *fb,
size_t len, size_t *n);
static int rfc822_entry_count (header_t, size_t *num);
static int rfc822_entry_name (header_t h, size_t num, char *buf,
size_t buflen, size_t *total);
static int rfc822_entry_value (header_t h, size_t num, char *buf,
size_t buflen, size_t *total);
static ssize_t rfc822_get_data (header_t h, char *buf, size_t buflen,
off_t off, int *err);
static int rfc822_get_value (header_t h, const char *fn,
char *fb, size_t len, size_t *n);
struct _rfc822
{
......@@ -57,6 +62,9 @@ rfc822_init (header_t *ph, const char *blurb, size_t len)
h->_parse = rfc822_parse;
h->_get_value = rfc822_get_value;
h->_set_value = rfc822_set_value;
h->_entry_count = rfc822_entry_count;
h->_entry_name = rfc822_entry_name;
h->_entry_value = rfc822_entry_value;
h->_get_data = rfc822_get_data;
status = h->_parse (h, blurb, len);
......@@ -90,6 +98,14 @@ rfc822_destroy (header_t *ph)
}
}
/*
* Parsing is done in a rather simple fashion.
* meaning we just consider an entry to be
* a field-name an a field-value. So they
* maybe duplicate of field-name like "Received"
* they are just put in the array, see _get_value()
* on how to handle the case.
*/
static int
rfc822_parse (header_t h, const char *blurb, size_t len)
{
......@@ -118,8 +134,8 @@ rfc822_parse (header_t h, const char *blurb, size_t len)
for (header_start = rfc->blurb;; header_start = ++header_end)
{
/* get a header, a header is :
field-name ':' field-body1
[ ' ' '\t' field-body2 ] '\r' '\n'
* field-name ':' ' ' field-value '\r' '\n'
* [ (' ' | '\t') field-value '\r' '\n' ]
*/
for (header_start2 = header_start;;header_start2 = ++header_end)
{
......@@ -195,36 +211,124 @@ rfc822_set_value (header_t h, const char *fn, const char *fv,
}
static int
rfc822_get_value (header_t h, const char *fn, char *fv, size_t len, size_t *n)
rfc822_get_value (header_t h, const char *name, char *buffer,
size_t buflen, size_t *n)
{
size_t i = 0;
size_t j = 0;
size_t name_len, fn_len, fv_len;
size_t name_len;
size_t total = 0, fn_len = 0, fv_len = 0;
int threshold;
rfc822_t rfc;
if (h == NULL || fn == NULL || (rfc = (rfc822_t)h->data) == NULL)
if (h == NULL || name == NULL ||
(rfc = (rfc822_t)h->data) == NULL)
return EINVAL;
for (name_len = strlen (fn), i = 0; i < rfc->hdr_count; i++)
/* we set the threshold to be 1 less for the null */
threshold = --buflen;
/*
* Caution: We may have more then one value for a field
* name, for example a "Received" field-name is added by
* each passing MTA. The way that the parsing (_parse())
* is done it's not take to account. So we just stuff in
* the buffer all the field-values to a corresponding field-name.
* FIXME: Should we kosher the output ? meaning replace
* occurences of " \t\r\n" for spaces ? for now we don't.
*/
for (name_len = strlen (name), i = 0; i < rfc->hdr_count; i++)
{
fn_len = rfc->hdr[i].fn_end - rfc->hdr[i].fn;
if (fn_len == name_len && memcmp (rfc->hdr[i].fn, fn, fn_len) == 0)
if (fn_len == name_len && memcmp (rfc->hdr[i].fn, name, fn_len) == 0)
{
fv_len = rfc->hdr[i].fv_end - rfc->hdr[i].fv;
j = (len < fv_len) ? len : fv_len;
if (fv)
memcpy (fv, rfc->hdr[i].fv, j);
break;
fv_len = (rfc->hdr[i].fv_end - rfc->hdr[i].fv);
total += fv_len;
/* can everything fit in the buffer */
if (buffer && threshold > 0)
{
threshold -= fv_len;
if (threshold > 0)
{
memcpy (buffer, rfc->hdr[i].fv, fv_len);
buffer += fv_len;
}
else if (threshold < 0)
{
threshold += fv_len;
memcpy (buffer, rfc->hdr[i].fv, threshold);
buffer += threshold;
threshold = 0;
}
}
}
}
if (fv)
fv[j] = '\0'; /* null terminated */
if (buffer)
*buffer = '\0'; /* null terminated */
if (n)
*n = fv_len;
*n = total;
return 0;
}
static int
rfc822_entry_count (header_t h, size_t *num)
{
rfc822_t rfc;
if (h == NULL || (rfc = (rfc822_t)h->data) == NULL)
return EINVAL;
if (num)
*num = rfc->hdr_count;
return 0;
}
static int
rfc822_entry_name (header_t h, size_t num, char *buf,
size_t buflen, size_t *nwritten)
{
rfc822_t rfc;
size_t len;
if (h == NULL || (rfc = (rfc822_t)h->data) == NULL)
return EINVAL;
if (rfc->hdr_count == 0 || num > rfc->hdr_count)
return ENOENT;
len = rfc->hdr[num].fn_end - rfc->hdr[num].fn;
/* save one for the null */
--buflen;
if (buf && buflen > 0)
{
buflen = (len > buflen) ? buflen : len;
memcpy (buf, rfc->hdr[num].fn, buflen);
buf[buflen] = '\0';
}
if (nwritten)
*nwritten = len;
return 0;
}
static int
rfc822_entry_value (header_t h, size_t num, char *buf,
size_t buflen, size_t *nwritten)
{
rfc822_t rfc;
size_t len;
if (h == NULL || (rfc = (rfc822_t)h->data) == NULL)
return EINVAL;
if (rfc->hdr_count == 0 || num > rfc->hdr_count)
return ENOENT;
len = rfc->hdr[num].fv_end - rfc->hdr[num].fv;
/* save one for the null */
--buflen;
if (buf && buflen > 0)
{
buflen = (len > buflen) ? buflen : len;
memcpy (buf, rfc->hdr[num].fv, buflen);
buf[buflen] = '\0';
}
if (nwritten)
*nwritten = len;
return 0;
}
ssize_t
static ssize_t
rfc822_get_data (header_t h, char *buf, size_t buflen, off_t off, int *err)
{
rfc822_t rfc;
......
......@@ -47,6 +47,7 @@ url_init (url_t * purl, const char *name)
registrar_t reg = NULL;
size_t name_len;
int id;
size_t i, entry_count = 0;
/* Sanity checks */
if (name == NULL || *name == '\0')
......@@ -55,6 +56,22 @@ url_init (url_t * purl, const char *name)
name_len = strlen (name);
/* Search for a known scheme */
registrar_entry_count (&entry_count);
for (i = 0; i < entry_count; i++)
{
if (registrar_entry (i, &ureg, &mreg, &id) == 0)
{
size_t scheme_len;
if (ureg && ureg->scheme &&
name_len > (scheme_len = strlen (ureg->scheme)) &&
memcmp (name, ureg->scheme, scheme_len) == 0)
{
status = 0;
break;
}
}
}
/*
while (registrar_list (&ureg, &mreg, &id, &reg) == 0)
{
size_t scheme_len;
......@@ -66,6 +83,7 @@ url_init (url_t * purl, const char *name)
break;
}
}
*/
/* Found one initialize it */
if (status == 0)
......