Commit 0b3ced06 0b3ced0625d37c283632e93f0d49360c668cb459 by Alain Magloire

Adding more comments, and in message_destroy make sure we

destroy all the objects attached to it.
1 parent 33e314b0
......@@ -53,6 +53,12 @@
#define ATTRIBUTE_IS_DELETED(flag) (flag & MU_ATTRIBUTE_DELETED)
#define ATTRIBUTE_IS_EQUAL(flag1, flag2) (flag1 == flag2)
struct _unix_message;
struct _unix_data;
typedef struct _unix_data* unix_data_t;
typedef struct _unix_message* unix_message_t;
static int unix_create (mailbox_t *pmbox, const char *name);
static void unix_destroy (mailbox_t *pmbox);
......@@ -64,7 +70,7 @@ struct mailbox_registrar _mailbox_unix_registrar =
/* Keep the position of where the header and body starts and ends.
old_flags is the "Status:" message. */
typedef struct _unix_message
struct _unix_message
{
/* Offset of the parts of the messages in the mailbox. */
off_t header_from;
......@@ -90,7 +96,7 @@ typedef struct _unix_message
/* A message attach to it. */
message_t message;
} *unix_message_t;
};
/* The umessages is an array of pointers that contains umessages_count of
unix_message_t*; umessages[umessages_count]. We do it this because
......@@ -98,7 +104,7 @@ typedef struct _unix_message
the pointers someone has on the messages. Thanks to <Dave Inglis> for
pointing this out. The messages_count is the count number of messages
parsed so far. */
typedef struct _unix_data
struct _unix_data
{
unix_message_t *umessages;
size_t umessages_count;
......@@ -118,8 +124,9 @@ typedef struct _unix_data
char *date;
off_t off;
} *unix_data_t;
};
/* Mailbox implementation. */
static int unix_open (mailbox_t mbox, int flag);
static int unix_close (mailbox_t mbox);
static int unix_get_message (mailbox_t, size_t msgno, message_t *msg);
......@@ -249,6 +256,7 @@ unix_create (mailbox_t *pmbox, const char *name)
return 0; /* okdoke */
}
/* Free all ressources associated with Unix mailbox. */
static void
unix_destroy (mailbox_t *pmbox)
{
......
......@@ -22,8 +22,7 @@
/* Parsing.
* The approach is to detect the "From " as start of a
* new message, give the position of the header and scan
* until "\n" then set header_end, set body position, if we have
* a Content-Length field jump to the point if not
* until "\n" then set header_end, set body position,
* scan until we it another "From " and set body_end.
*
************************************
......@@ -187,7 +186,7 @@ do \
(buf[4] == 'U' || buf[4] == 'u') && \
(buf[5] == 'S' || buf[5] == 's') && (buf[6] == ':'))
/* notification */
/* Notification. */
#define MAILBOX_NOTIFICATION(mbox,which,bailing) \
do \
{ \
......@@ -201,7 +200,7 @@ do \
} \
} while (0)
/* notifications ADD_MESG */
/* Notifications ADD_MESG. */
#define DISPATCH_ADD_MSG(mbox,mud) \
do \
{ \
......@@ -218,17 +217,12 @@ do \
unix_ilock (mbox, MU_LOCKER_WRLOCK); \
} while (0);
/* notification MBX_PROGRESS
* We do not want to fire up the progress notification
* every line, it will be too expensive, so we do it
* arbitrarely every 10 000 Lines.
* FIXME: maybe this should be configurable.
*/
/*
* This is more tricky we can not leave the mum
* struct incomplete. So we only tell them about
* the complete messages.
*/
/* Notification MBX_PROGRESS
We do not want to fire up the progress notification every line, it will be
too expensive, so we do it arbitrarely every 10 000 Lines.
FIXME: maybe this should be configurable. */
/* This is more tricky we can not leave the mum struct incomplete. So we
only tell them about the complete messages. */
#define DISPATCH_PROGRESS(mbox,mud) \
do \
{ \
......@@ -249,25 +243,7 @@ do \
} \
} while (0)
#if 0
/* skip a function call, ?? do we gain that much */
#define ATTRIBUTE_CREATE(attr, m, mbox) \
do \
{ \
attr = calloc (1, sizeof(*(attr))); \
attr->owner = m; \
if ((attr) == NULL) \
{ \
unix_iunlock (mbox); \
unix_unlock (mbox); \
return ENOMEM; \
} \
} while (0)
#else
# define ATTRIBUTE_CREATE
#endif
/* allocate slots for the new messages */
/* Allocate slots for the new messages. */
/* size_t num = 2 * ((mud)->messages_count) + 10; */
#define ALLOCATE_MSGS(mbox,mud) \
do \
......@@ -303,7 +279,7 @@ unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
int inheader;
int inbody;
off_t total = 0;
unix_data_t mud;
unix_data_t mud = mbox->data;
unix_message_t mum = NULL;
int status = 0;
size_t lines;
......@@ -313,21 +289,20 @@ unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
int zn, isfrom = 0;
char *temp;
/* sanity */
if (mbox == NULL ||
(mud = (unix_data_t)mbox->data) == NULL)
/* Sanity. */
if (mud == NULL)
return EINVAL;
/* save the timestamp and size */
/* Save the timestamp and size. */
status = stream_size (mbox->stream, &(mud->size));
if (status != 0)
return status;
/* grab the locks */
/* Grab the locks. */
unix_ilock (mbox, MU_LOCKER_WRLOCK);
unix_lock (mbox, MU_LOCKER_RDLOCK);
/* seek to the starting point */
/* Seek to the starting point. */
if (mud->umessages && msgno > 0 && mud->messages_count > 0
&& msgno <= mud->messages_count)
{
......@@ -352,7 +327,7 @@ unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
VALID(buf, temp, isfrom, zn);
isfrom = (isfrom) ? 1 : 0;
/* which part of the message are we in ? */
/* Which part of the message are we in ? */
inheader = isfrom | ((!nl) & inheader);
inbody = (!isfrom) & (!inheader);
......@@ -360,10 +335,10 @@ unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
if (inheader)
{
/* new message */
/* New message. */
if (isfrom)
{
/* signal the end of the body */
/* Signal the end of the body. */
if (mum && !mum->body_end)
{
mum->body_end = total - n - newline;
......@@ -371,7 +346,7 @@ unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
if (do_notif)
DISPATCH_ADD_MSG(mbox, mud);
}
/* allocate_msgs will initialize mum */
/* Allocate_msgs will initialize mum. */
ALLOCATE_MSGS(mbox, mud);
mud->messages_count++;
mum = mud->umessages[mud->messages_count - 1];
......@@ -391,10 +366,10 @@ unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
}
}
/* body */
/* Body. */
if (inbody)
{
/* set the body position */
/* Set the body position. */
if (mum && !mum->body)
{
mum->body = total - n + nl;
......@@ -405,11 +380,11 @@ unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
newline = nl;
/* every 50 mesgs update the lock, it should be every minute */
/* Every 50 mesgs update the lock, it should be every minute. */
if ((mud->messages_count % 50) == 0)
unix_touchlock (mbox);
/* ping them every 1000 lines */
/* Ping them every 1000 lines. */
if (do_notif)
if (((lines +1) % 1000) == 0)
DISPATCH_PROGRESS(mbox, mud);
......@@ -429,4 +404,3 @@ unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
*pcount = mud->messages_count;
return status;
}
......
......@@ -27,6 +27,7 @@
#include <time.h>
#include <string.h>
/* FIXME: This should be part of the address_t object when implemented. */
static int extract_addr(const char *s, size_t n, char **presult,
size_t *pnwrite);
static int message_read (stream_t is, char *buf, size_t buflen,
......@@ -35,6 +36,7 @@ static int message_write (stream_t os, const char *buf, size_t buflen,
off_t off, size_t *pnwrite);
static int message_get_fd (stream_t stream, int *pfd);
/* Allocate ressources for the message_t. */
int
message_create (message_t *pmsg, void *owner)
{
......@@ -59,31 +61,45 @@ message_destroy (message_t *pmsg, void *owner)
if (msg->owner == owner)
{
/* notify the listeners */
/* Notify the listeners. */
/* FIXME: to be removed since we do not supoort this event. */
if (msg->event_num)
{
message_notification (msg, MU_EVT_MSG_DESTROY);
free (msg->event);
}
/* header */
header_destroy (&(msg->header), owner);
/* attribute */
attribute_destroy (&(msg->attribute), owner);
/* stream */
stream_destroy (&(msg->stream), owner);
/* if sometype of floating/temporary message */
body_destroy (&(msg->body), owner);
/* notifications are done */
/* check again for resurrection before free()ing
* the memory maybe it was clone, if yes we can not
* free the pointer.
*
*/
/* Header. */
if (msg->header)
header_destroy (&(msg->header), owner);
if (msg->header)
header_destroy (&(msg->header), msg);
/* Attribute. */
if (msg->attribute)
attribute_destroy (&(msg->attribute), owner);
if (msg->attribute)
attribute_destroy (&(msg->attribute), msg);
/* Stream. */
if (msg->stream)
stream_destroy (&(msg->stream), owner);
if (msg->stream)
stream_destroy (&(msg->stream), msg);
/* Body. */
if (msg->body)
body_destroy (&(msg->body), owner);
if (msg->body)
body_destroy (&(msg->body), msg);
/* Mime. */
if (msg->mime)
mime_destroy (&(msg->mime));
free (msg);
}
/* loose the link */
/* Loose the link */
*pmsg = NULL;
}
}
......@@ -94,8 +110,8 @@ message_get_header (message_t msg, header_t *phdr)
if (msg == NULL || phdr == NULL)
return EINVAL;
/* is it a floating mesg */
if (msg->header == NULL && msg->owner == NULL)
/* Is it a floating mesg */
if (msg->header == NULL)
{
header_t header;
int status = header_create (&header, NULL, 0, msg);
......@@ -114,8 +130,9 @@ message_set_header (message_t msg, header_t hdr, void *owner)
return EINVAL;
if (msg->owner != owner)
return EACCES;
/* make sure we destoy the old if it was own by the mesg */
header_destroy (&(msg->header), msg);
/* Make sure we destoy the old if it was own by the mesg */
/* FIXME: I do not know if somebody has already a ref on this ? */
/* header_destroy (&(msg->header), msg); */
msg->header = hdr;
return 0;
}
......@@ -126,7 +143,7 @@ message_get_body (message_t msg, body_t *pbody)
if (msg == NULL || pbody == NULL)
return EINVAL;
/* is it a floating mesg */
/* Is it a floating mesg. */
if (msg->body == NULL)
{
body_t body;
......@@ -146,8 +163,9 @@ message_set_body (message_t msg, body_t body, void *owner)
return EINVAL;
if (msg->owner != owner)
return EACCES;
/* make sure we destoy the old if it was own by the mesg */
body_destroy (&(msg->body), msg);
/* Make sure we destoy the old if it was own by the mesg. */
/* FIXME: I do not know if somebody has already a ref on this ? */
/* body_destroy (&(msg->body), msg); */
msg->body = body;
return 0;
}
......@@ -205,7 +223,7 @@ message_lines (message_t msg, size_t *plines)
size_t hlines, blines;
if (msg == NULL)
return EINVAL;
/* Overload */
/* Overload. */
if (msg->_lines)
return msg->_lines (msg, plines);
if (plines)
......@@ -272,11 +290,11 @@ message_from (message_t msg, char *buf, size_t len, size_t *pnwrite)
if (msg == NULL)
return EINVAL;
/* did they provide a way to get it */
/* Did they provide a way to get it ? */
if (msg->_from)
return msg->_from (msg, buf, len, pnwrite);
/* can it be extracted from the From: */
/* Can it be extracted from the From: */
message_get_header (msg, &header);
status = header_get_value (header, MU_HEADER_FROM, NULL, 0, &n);
if (status == 0 && n != 0)
......@@ -335,14 +353,14 @@ message_received (message_t msg, char *buf, size_t len, size_t *pnwrite)
size_t n;
if (msg == NULL)
return EINVAL;
/* is it provided */
/* Is it provided ? */
if (msg->_received)
return msg->_received (msg, buf, len, pnwrite);
/* FIXME: extract the time from "Date:" */
/* FIXME: extract the time from "Date:". */
/* catch all */
/* FIXME: ctime() is not thread safe use strftime() */
/* Catch all. */
/* FIXME: ctime() is not thread safe use strftime(). */
t = time (NULL);
n = strlen (ctime (&t));
......@@ -406,7 +424,7 @@ message_get_uidl (message_t msg, char *buffer, size_t buflen, size_t *pwritten)
int
message_set_uidl (message_t msg, int (* _get_uidl)
__P ((message_t msg, char *buffer, size_t buflen, size_t *pwritten)), void *owner)
__P ((message_t, char *, size_t, size_t *)), void *owner)
{
if (msg == NULL)
return EINVAL;
......@@ -527,7 +545,7 @@ message_register (message_t msg, size_t type,
if (msg == NULL || action == NULL || type == 0)
return EINVAL;
/* find a free spot */
/* Find a free spot. */
for (i = 0; i < msg->event_num; i++)
{
event = &(msg->event[i]);
......@@ -633,7 +651,7 @@ message_write (stream_t os, const char *buf, size_t buflen,
if (os == NULL || (msg = os->owner) == NULL)
return EINVAL;
/* skip the obvious */
/* Skip the obvious. */
if (buf == NULL || *buf == '\0' || buflen == 0)
{
if (pnwrite)
......@@ -649,7 +667,7 @@ message_write (stream_t os, const char *buf, size_t buflen,
while (!msg->hdr_done && (nl = memchr (buf, '\n', buflen)) != NULL)
{
len = nl - buf + 1;
/* allocate more buffer to hold the header */
/* Allocate more buffer to hold the header. */
thdr = realloc (msg->hdr_buf, msg->hdr_buflen + len);
if (thdr == NULL)
{
......@@ -662,8 +680,8 @@ message_write (stream_t os, const char *buf, size_t buflen,
msg->hdr_buf = thdr;
memcpy (msg->hdr_buf + msg->hdr_buflen, buf, len);
msg->hdr_buflen += len;
/* we detect an empty line .i.e "^\n$" this signal the end
* of the header */
/* We detect an empty line .i.e "^\n$" this signal the end of the
header. */
if (buf == nl)
{
header_destroy (&(msg->header), msg);
......@@ -683,7 +701,7 @@ message_write (stream_t os, const char *buf, size_t buflen,
}
}
/* message header is not complete but was not a full line */
/* Message header is not complete but was not a full line. */
if (!msg->hdr_done && buflen > 0)
{
char *thdr = realloc (msg->hdr_buf, msg->hdr_buflen + buflen);
......@@ -700,7 +718,7 @@ message_write (stream_t os, const char *buf, size_t buflen,
msg->hdr_buflen += buflen;
buflen = 0;
}
else if (buflen > 0) /* in the body */
else if (buflen > 0) /* In the body. */
{
stream_t bs;
body_t body;
......@@ -735,11 +753,12 @@ message_get_fd (stream_t stream, int *pfd)
if (stream == NULL || (msg = stream->owner) == NULL)
return EINVAL;
/* Probably being lazy, then create a body for the stream */
/* Probably being lazy, then create a body for the stream. */
if (msg->body == NULL)
{
int status = body_create (&body, msg);
if (status != 0 )
return status;
msg->body = body;
}
......@@ -758,7 +777,7 @@ extract_addr (const char *s, size_t n, char **presult, size_t *pnwrite)
if (s == NULL || n == 0 || presult == NULL)
return EINVAL;
/* skip the double quotes */
/* Skip the double quotes. */
p = memchr (s, '\"', n);
if (p != NULL)
{
......@@ -775,7 +794,7 @@ extract_addr (const char *s, size_t n, char **presult, size_t *pnwrite)
}
}
/* <name@hostname> ?? */
/* <name@hostname> ?? */
p = memchr (s, '<', n);
if (p != NULL)
{
......@@ -785,7 +804,7 @@ extract_addr (const char *s, size_t n, char **presult, size_t *pnwrite)
p2 = memchr (p, ' ', p1 - p);
if (p2 == NULL)
{
/* the NULL is already accounted for */
/* The NULL is already accounted for. */
*presult = calloc (1, p1 - p);
if (*presult == NULL)
return ENOMEM;
......@@ -796,7 +815,7 @@ extract_addr (const char *s, size_t n, char **presult, size_t *pnwrite)
}
}
}
/* name@domain */
/* name@domain */
p = memchr (s, '@', n);
if (p != NULL)
{
......