Commit 24d3722e 24d3722ecab73da942988dc586ebfc28748fb873 by Alain Magloire

Cleanup again and all of this done with one hand !!!

We're moving closer to cleaning the repository and using
autoconf and all.  But my keyboard quota is almost expired.
1 parent 75a14dc5
......@@ -23,7 +23,7 @@
#include <errno.h>
int
attribute_create (attribute_t *pattr)
attribute_create (attribute_t *pattr, void *owner)
{
attribute_t attr;
if (pattr == NULL)
......@@ -31,15 +31,18 @@ attribute_create (attribute_t *pattr)
attr = calloc (1, sizeof(*attr));
if (attr == NULL)
return ENOMEM;
attr->owner = owner;
*pattr = attr;
return 0;
}
void
attribute_destroy (attribute_t *pattr)
attribute_destroy (attribute_t *pattr, void *owner)
{
if (pattr && *pattr)
{
attribute_t attr = *pattr;
if (attr->owner != owner)
free (*pattr);
/* loose the link */
*pattr = NULL;
......@@ -48,68 +51,144 @@ attribute_destroy (attribute_t *pattr)
}
int
attribute_get_flags (attribute_t attr, int *pflags)
{
if (attr->_get_flags)
return attr->_get_flags (attr, pflags);
if (pflags)
*pflags = attr->flags;
return 0;
}
int
attribute_set_flags (attribute_t attr, int flags)
{
if (attr->_set_flags)
return attr->_set_flags (attr, flags);
attr->flags |= flags;
return 0;
}
int
attribute_set_get_flags (attribute_t attr, int (*_get_flags)
(attribute_t, int *), void *owner)
{
if (attr == NULL)
return EINVAL;
if (attr->owner != owner)
return EACCES;
attr->_get_flags = _get_flags;
return 0;
}
int
attribute_set_set_flags (attribute_t attr, int (*_set_flags)
(attribute_t, int), void *owner)
{
if (attr == NULL)
return EINVAL;
if (attr->owner != owner)
return EACCES;
attr->_set_flags = _set_flags;
return 0;
}
int
attribute_set_unset_flags (attribute_t attr, int (*_unset_flags)
(attribute_t, int), void *owner)
{
if (attr == NULL)
return EINVAL;
if (attr->owner != owner)
return EACCES;
attr->_unset_flags = _unset_flags;
return 0;
}
int
attribute_set_seen (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return EINVAL;
attr->flag |= MU_ATTRIBUTE_SEEN;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
attr->flags |= MU_ATTRIBUTE_SEEN;
return 0;
}
int
attribute_set_answered (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return EINVAL;
attr->flag |= MU_ATTRIBUTE_ANSWERED;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
attr->flags |= MU_ATTRIBUTE_ANSWERED;
return 0;
}
int
attribute_set_flagged (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return EINVAL;
attr->flag |= MU_ATTRIBUTE_FLAGGED;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
attr->flags |= MU_ATTRIBUTE_FLAGGED;
return 0;
}
int
attribute_set_read (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return EINVAL;
attr->flag |= MU_ATTRIBUTE_READ;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
attr->flags |= MU_ATTRIBUTE_READ;
return 0;
}
int
attribute_set_deleted (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return EINVAL;
attr->flag |= MU_ATTRIBUTE_DELETED;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
attr->flags |= MU_ATTRIBUTE_DELETED;
return 0;
}
int
attribute_set_draft (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return EINVAL;
attr->flag |= MU_ATTRIBUTE_DRAFT;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
attr->flags |= MU_ATTRIBUTE_DRAFT;
return 0;
}
int
attribute_set_recent (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return EINVAL;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
if (attr == NULL)
{
attr->flag &= ~MU_ATTRIBUTE_READ;
attr->flag &= ~MU_ATTRIBUTE_SEEN;
attr->flags &= ~MU_ATTRIBUTE_READ;
attr->flags &= ~MU_ATTRIBUTE_SEEN;
return 0;
}
return EACCES;
......@@ -118,131 +197,176 @@ attribute_set_recent (attribute_t attr)
int
attribute_is_seen (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
return attr->flag & MU_ATTRIBUTE_SEEN;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
return attr->flags & MU_ATTRIBUTE_SEEN;
}
int
attribute_is_answered (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
return attr->flag & MU_ATTRIBUTE_ANSWERED;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
return attr->flags & MU_ATTRIBUTE_ANSWERED;
}
int
attribute_is_flagged (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
return attr->flag & MU_ATTRIBUTE_FLAGGED;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
return attr->flags & MU_ATTRIBUTE_FLAGGED;
}
int
attribute_is_read (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
return attr->flag & MU_ATTRIBUTE_READ;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
return attr->flags & MU_ATTRIBUTE_READ;
}
int
attribute_is_deleted (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
return attr->flag & MU_ATTRIBUTE_DELETED;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
return attr->flags & MU_ATTRIBUTE_DELETED;
}
int
attribute_is_draft (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
return attr->flag & MU_ATTRIBUTE_DRAFT;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
return attr->flags & MU_ATTRIBUTE_DRAFT;
}
int
attribute_is_recent (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
/* something is recent when it is not read and not seen. */
return (attr->flag == 0
|| ! ((attr->flag & MU_ATTRIBUTE_SEEN)
&& (attr->flag & MU_ATTRIBUTE_READ)));
return (attr->flags == 0
|| ! ((attr->flags & MU_ATTRIBUTE_SEEN)
&& (attr->flags & MU_ATTRIBUTE_READ)));
}
int
attribute_unset_seen (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
attr->flag &= ~MU_ATTRIBUTE_SEEN;
return 0;
if (attr->_unset_flags)
status = attr->_unset_flags (attr, MU_ATTRIBUTE_SEEN);
attr->flags &= ~MU_ATTRIBUTE_SEEN;
return status;
}
int
attribute_unset_answered (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
attr->flag &= ~MU_ATTRIBUTE_ANSWERED;
return 0;
if (attr->_unset_flags)
status = attr->_unset_flags (attr, MU_ATTRIBUTE_ANSWERED);
attr->flags &= ~MU_ATTRIBUTE_ANSWERED;
return status;
}
int
attribute_unset_flagged (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
attr->flag &= ~MU_ATTRIBUTE_FLAGGED;
return 0;
if (attr->_unset_flags)
status = attr->_unset_flags (attr, MU_ATTRIBUTE_FLAGGED);
attr->flags &= ~MU_ATTRIBUTE_FLAGGED;
return status;
}
int
attribute_unset_read (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
attr->flag &= ~MU_ATTRIBUTE_READ;
return 0;
if (attr->_unset_flags)
status = attr->_unset_flags (attr, MU_ATTRIBUTE_READ);
attr->flags &= ~MU_ATTRIBUTE_READ;
return status;
}
int
attribute_unset_deleted (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
attr->flag &= ~MU_ATTRIBUTE_DELETED;
return 0;
if (attr->_unset_flags)
status = attr->_unset_flags (attr, MU_ATTRIBUTE_DELETED);
attr->flags &= ~MU_ATTRIBUTE_DELETED;
return status;
}
int
attribute_unset_draft (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
attr->flag &= ~MU_ATTRIBUTE_DRAFT;
return 0;
if (attr->_unset_flags)
status = attr->_unset_flags (attr, MU_ATTRIBUTE_DRAFT);
attr->flags &= ~MU_ATTRIBUTE_DRAFT;
return status;
}
int
attribute_unset_recent (attribute_t attr)
{
int status = 0;
if (attr == NULL)
return 0;
attr->flag |= MU_ATTRIBUTE_SEEN;
return 0;
if (attr->_unset_flags)
status = attr->_unset_flags (attr, MU_ATTRIBUTE_SEEN);
attr->flags |= MU_ATTRIBUTE_SEEN;
return status;
}
int
attribute_is_equal (attribute_t attr, attribute_t attr2)
{
int status = 0;
if (attr == NULL || attr2 == NULL)
return 0;
return attr->flag == attr2->flag;
if (attr->_get_flags)
status = attr->_get_flags (attr, &(attr->flags));
return attr->flags == attr2->flags;
}
int
......@@ -255,14 +379,12 @@ attribute_copy (attribute_t dest, attribute_t src)
}
int
string_to_attribute (const char *buffer, attribute_t *pattr)
string_to_flags (const char *buffer, int *pflags)
{
const char *sep;
int status;
status = attribute_create (pattr);
if (status != 0)
return status;
if (pflags == NULL)
return EINVAL;
/* Set the attribute */
if (strncasecmp (buffer, "Status:", 7) == 0)
......@@ -271,22 +393,22 @@ string_to_attribute (const char *buffer, attribute_t *pattr)
sep++;
}
else
sep = buffer;
return EINVAL;
while (*sep == ' ') sep++; /* glob spaces */
if (strchr (sep, 'R') != NULL || strchr (sep, 'r') != NULL)
attribute_set_read (*pattr);
*pflags |= MU_ATTRIBUTE_READ;
if (strchr (sep, 'O') != NULL || strchr (sep, 'o') != NULL)
attribute_set_seen (*pattr);
*pflags |= MU_ATTRIBUTE_SEEN;
if (strchr (sep, 'A') != NULL || strchr (sep, 'a') != NULL)
attribute_set_answered (*pattr);
*pflags |= MU_ATTRIBUTE_ANSWERED;
if (strchr (sep, 'F') != NULL || strchr (sep, 'f') != NULL)
attribute_set_flagged (*pattr);
*pflags |= MU_ATTRIBUTE_FLAGGED;
return 0;
}
int
attribute_to_string (attribute_t attr, char *buffer, size_t len, size_t *pn)
int
flags_to_string (int flags, char *buffer, size_t len, size_t *pn)
{
char status[32];
char a[8];
......@@ -294,14 +416,16 @@ attribute_to_string (attribute_t attr, char *buffer, size_t len, size_t *pn)
*status = *a = '\0';
if (attribute_is_seen (attr))
if (flags & MU_ATTRIBUTE_SEEN)
strcat (a, "R");
if (attribute_is_answered (attr))
if (flags & MU_ATTRIBUTE_ANSWERED)
strcat (a, "A");
if (attribute_is_flagged (attr))
if (flags & MU_ATTRIBUTE_FLAGGED)
strcat (a, "F");
if (attribute_is_read (attr))
if (flags & MU_ATTRIBUTE_READ)
strcat (a, "O");
if (flags & MU_ATTRIBUTE_DELETED)
strcat (a, "d");
if (*a != '\0')
{
......
......@@ -20,7 +20,7 @@
# include "config.h"
#endif
#include <header.h>
#include <header0.h>
#include <io0.h>
#include <string.h>
#include <stdlib.h>
......@@ -33,30 +33,6 @@ static int header_read (stream_t is, char *buf, size_t buflen,
static int header_write (stream_t os, const char *buf, size_t buflen,
off_t off, size_t *pnwrite);
struct _hdr
{
char *fn;
char *fn_end;
char *fv;
char *fv_end;
};
struct _header
{
/* Owner. */
void *owner;
/* Data. */
char *blurb;
size_t blurb_len;
size_t hdr_count;
struct _hdr *hdr;
/* Streams. */
stream_t stream;
int (*_get_value) __P ((header_t, const char *, char *, size_t , size_t *));
};
int
header_create (header_t *ph, const char *blurb, size_t len, void *owner)
{
......@@ -66,6 +42,7 @@ header_create (header_t *ph, const char *blurb, size_t len, void *owner)
return ENOMEM;
h->owner = owner;
/* Ignore the return value. */
header_parse (h, blurb, len);
*ph = h;
......@@ -83,7 +60,9 @@ header_destroy (header_t *ph, void *owner)
if (h->owner == owner)
{
stream_destroy (&(h->stream), h);
if (h->hdr)
free (h->hdr);
if (h->blurb)
free (h->blurb);
free (h);
}
......@@ -207,8 +186,7 @@ header_parse (header_t header, const char *blurb, int len)
}
/* FIXME: grossly inneficient, to many copies and reallocating.
* This all header business need a good rewrite.
*/
This all header business need a good rewrite. */
int
header_set_value (header_t header, const char *fn, const char *fv, int replace)
{
......@@ -218,11 +196,14 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
if (header == NULL || fn == NULL || fv == NULL)
return EINVAL;
/* Easy approach: if replace, overwrite the field-{namve,value}
and readjust the pointers by calling header_parse ()
this is wastefull, we're just fragmenting the memory
it can be done better. But that may imply a rewite of the headers
So for another day. */
/* Try to fill out the buffer, if we know how. */
if (header->_set_value != NULL)
return header->_set_value (header, fn, fv, replace);
/* Easy approach: if replace, overwrite the field-{name,value} and readjust
the pointers by calling header_parse () this is wastefull, we're just
fragmenting the memory it can be done better. But that may imply a
rewite of the headers So for another day. */
if (replace)
{
size_t name_len;
......@@ -251,8 +232,8 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
}
}
/* Replacing was taking care of above now just add to
the end the new header. Really not cute. */
/* Replacing was taking care of above now just add to the end the new
header. Really not cute. */
len = strlen (fn) + strlen (fv) + 1 + 1 + 1 + 1;
blurb = calloc (header->blurb_len + len, 1);
if (blurb == NULL)
......@@ -266,20 +247,6 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
}
int
header_set_get_value (header_t header, int (*_get_value)
(header_t, const char *, char *, size_t, size_t *),
void *owner)
{
if (header == NULL)
return EINVAL;
if (header->owner != owner)
return EACCES;
header->_get_value = _get_value;
return 0;
}
int
header_get_value (header_t header, const char *name, char *buffer,
size_t buflen, size_t *pn)
{
......@@ -287,20 +254,61 @@ header_get_value (header_t header, const char *name, char *buffer,
size_t name_len;
size_t total = 0, fn_len = 0, fv_len = 0;
int threshold;
int err = 0;
if (header == NULL || name == NULL)
return EINVAL;
if (header->_get_value != NULL)
return header->_get_value (header, name, buffer, buflen, pn);
/* Try to fill out the buffer, if we know how. */
if (header->blurb == NULL)
{
stream_t is;
err = header_get_stream (header, &is);
if (err != 0)
return err;
else
{
char buf[1024];
char *tbuf;
size_t nread = 0;
do
{
err = stream_read (is, buf, sizeof (buf), header->temp_blurb_len,
&nread);
if (err != 0
|| (tbuf = realloc (header->temp_blurb,
header->temp_blurb_len + nread)) == NULL)
{
free (header->temp_blurb);
header->temp_blurb = NULL;
header->temp_blurb_len = 0;
return err;
}
else
header->temp_blurb = tbuf;
memcpy (header->temp_blurb + header->temp_blurb_len, buf, nread);
header->temp_blurb_len += nread;
} while (nread != 0);
/* parse it. */
header_parse (header, header->temp_blurb, header->temp_blurb_len);
free (header->temp_blurb);
header->temp_blurb = NULL;
header->temp_blurb_len = 0;
}
}
/* 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. */
/* 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 < header->hdr_count; i++)
{
fn_len = header->hdr[i].fn_end - header->hdr[i].fn;
......@@ -332,48 +340,35 @@ header_get_value (header_t header, const char *name, char *buffer,
*buffer = '\0'; /* Null terminated. */
if (pn)
*pn = total;
/* Check if they provided a hook. */
if (total == 0)
{
int err = ENOENT;
/* Check if they provided a hook. */
err = ENOENT;
if (header->_get_value != NULL)
err = header->_get_value (header, name, buffer, buflen, pn);
/* Cache it locally. */
/* Success. Cache it locally. */
if (err == 0)
header_set_value (header, name, buffer, 0);
return err;
}
return 0;
}
int
header_entry_count (header_t header, size_t *pnum)
{
if (header == NULL)
{
if (pnum)
*pnum = 0;
return EINVAL;
}
if (pnum)
*pnum = header->hdr_count;
return 0;
return err;
}
int
header_lines (header_t header, size_t *plines)
{
int n;
size_t t = 0;
size_t lines = 0;
if (header == NULL)
return EINVAL;
for (n = header->blurb_len - 1; n >= 0; n--)
{
if (header->blurb[n] == '\n')
t++;
lines++;
}
if (plines)
*plines = t;
*plines = lines;
return 0;
}
......@@ -382,57 +377,50 @@ header_size (header_t header, size_t *pnum)
{
if (header == NULL)
return EINVAL;
if (pnum)
*pnum = header->blurb_len;
return 0;
}
int
header_entry_name (header_t header, size_t num, char *buf,
size_t buflen, size_t *nwritten)
header_set_get_value (header_t header, int (*_get_value)
(header_t, const char *, char *, size_t, size_t *),
void *owner)
{
size_t len;
if (header == NULL)
return EINVAL;
if (header->hdr_count == 0 || num > header->hdr_count)
return ENOENT;
len = header->hdr[num].fn_end - header->hdr[num].fn;
/* save one for the null */
--buflen;
if (buf && buflen > 0)
{
buflen = (len > buflen) ? buflen : len;
memcpy (buf, header->hdr[num].fn, buflen);
buf[buflen] = '\0';
}
if (nwritten)
*nwritten = len;
if (header->owner != owner)
return EACCES;
header->_get_value = _get_value;
return 0;
}
int
header_entry_value (header_t header, size_t num, char *buf,
size_t buflen, size_t *nwritten)
header_set_set_value (header_t header, int (*_set_value)
(header_t , const char *, const char *, int),
void *owner)
{
size_t len;
if (header == NULL)
return EINVAL;
if (header->hdr_count == 0 || num > header->hdr_count)
return ENOENT;
len = header->hdr[num].fv_end - header->hdr[num].fv;
/* Save one for the null. */
--buflen;
if (buf && buflen > 0)
{
buflen = (len > buflen) ? buflen : len;
memcpy (buf, header->hdr[num].fv, buflen);
buf[buflen] = '\0';
}
if (nwritten)
*nwritten = len;
if (header->owner != owner)
return EACCES;
header->_set_value = _set_value;
return 0;
}
int
header_set_stream (header_t header, stream_t stream, void *owner)
{
if (header == NULL)
return EINVAL;
if (header->owner != owner)
return EACCES;
header->stream = stream;
return 0;
}
static int
header_write (stream_t os, const char *buf, size_t buflen,
off_t off, size_t *pnwrite)
......
......@@ -34,17 +34,13 @@ extern "C" {
struct _attribute
{
size_t flag;
void *owner;
size_t flags;
int (*_get_flags) __P ((attribute_t, int *));
int (*_set_flags) __P ((attribute_t, int));
int (*_unset_flags) __P ((attribute_t, int));
};
#define MU_ATTRIBUTE_ANSWERED 0x01
#define MU_ATTRIBUTE_FLAGGED 0x02
#define MU_ATTRIBUTE_DELETED 0x04
#define MU_ATTRIBUTE_DRAFT 0x08
#define MU_ATTRIBUTE_SEEN 0x10
#define MU_ATTRIBUTE_READ 0x20
#define MU_ATTRIBUTE_RECENT 0x00
#ifdef __cplusplus
}
#endif
......
......@@ -35,8 +35,16 @@ extern "C" {
struct _attribute;
typedef struct _attribute * attribute_t;
extern int attribute_create __P ((attribute_t *));
extern void attribute_destroy __P ((attribute_t *));
#define MU_ATTRIBUTE_ANSWERED 0x01
#define MU_ATTRIBUTE_FLAGGED 0x02
#define MU_ATTRIBUTE_DELETED 0x04
#define MU_ATTRIBUTE_DRAFT 0x08
#define MU_ATTRIBUTE_SEEN 0x10
#define MU_ATTRIBUTE_READ 0x20
#define MU_ATTRIBUTE_RECENT 0x00
extern int attribute_create __P ((attribute_t *, void *));
extern void attribute_destroy __P ((attribute_t *, void *));
extern int attribute_is_seen __P ((attribute_t));
extern int attribute_is_answered __P ((attribute_t));
......@@ -62,14 +70,22 @@ 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_get_flags __P ((attribute_t, int *));
extern int attribute_set_flags __P ((attribute_t, int));
extern int attribute_set_set_flags __P ((attribute_t, int (*_set_flags)
__P ((attribute_t, int)), void *));
extern int attribute_set_unset_flags __P ((attribute_t, int (*_unset_flags)
__P ((attribute_t, int)), void *));
extern int attribute_set_get_flags __P ((attribute_t, int (*_get_flags)
__P ((attribute_t, int *)), void *));
extern int attribute_is_equal __P ((attribute_t att1, attribute_t att2));
extern int attribute_copy __P ((attribute_t dst,
attribute_t src));
extern int string_to_attribute __P ((const char *buf,
attribute_t *pattr));
extern int attribute_to_string __P ((attribute_t attr, char *buf,
extern int string_to_flags __P ((const char *buf, int *pattr));
extern int flags_to_string __P ((int flags, char *buf,
size_t len, size_t *));
#ifdef __cplusplus
......
......@@ -67,27 +67,27 @@ extern "C" {
struct _header;
typedef struct _header * header_t;
extern int header_create __P ((header_t *, const char *blurb,
size_t ln, void *owner));
extern void header_destroy __P ((header_t *, void *owner));
extern int header_create __P ((header_t *, const char *,
size_t, void *));
extern void header_destroy __P ((header_t *, void *));
extern int header_set_value __P ((header_t, const char *,
const char *, int));
extern int header_get_value __P ((header_t, const char *, char *,
size_t, size_t *));
extern int header_get_stream __P ((header_t, stream_t *));
extern int header_size __P ((header_t, size_t *));
extern int header_lines __P ((header_t, size_t *));
extern int header_set_value __P ((header_t, const char *fn,
const char *fv, int replace));
extern int header_set_stream __P ((header_t, stream_t, void *));
extern int header_set_set_value __P ((header_t, int (*_set_value)
__P ((header_t, const char *,
const char *, int)),
void *));
extern int header_set_get_value __P ((header_t, int (*_get_value)
__P ((header_t, const char *fn, char *buf,
size_t buflen, size_t *nwritten)),
void *owner));
extern int header_get_value __P ((header_t, const char *fn, char *buf,
size_t buflen, 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));
extern int header_get_stream __P ((header_t, stream_t *stream));
extern int header_size __P ((header_t, size_t *size));
extern int header_lines __P ((header_t, size_t *lines));
__P ((header_t, const char *,
char *, size_t, size_t *)),
void *));
#ifdef _cplusplus
}
......
......@@ -173,7 +173,7 @@ do \
{ \
if (*s == c0 || *s == c1) \
{ \
(mum)->old_attr->flag |= (type); \
(mum)->old_flags |= (type); \
break; \
} \
} \
......@@ -206,16 +206,16 @@ do \
do \
{ \
int bailing = 0; \
mailbox_unix_iunlock (mbox); \
unix_iunlock (mbox); \
MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_MSG_ADD, bailing); \
if (bailing != 0) \
{ \
if (pcount) \
*pcount = (mud)->messages_count; \
mailbox_unix_unlock (mbox); \
unix_unlock (mbox); \
return EINTR; \
} \
mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); \
unix_ilock (mbox, MU_LOCKER_WRLOCK); \
} while (0);
/* notification MBX_PROGRESS
......@@ -234,33 +234,38 @@ do \
{ \
{ \
int bailing = 0; \
mailbox_unix_iunlock (mbox); \
unix_iunlock (mbox); \
mud->messages_count--; \
MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_PROGRESS,bailing); \
if (bailing != 0) \
{ \
if (pcount) \
*pcount = (mud)->messages_count; \
mailbox_unix_unlock (mbox); \
unix_unlock (mbox); \
return EINTR; \
} \
mud->messages_count++; \
mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); \
unix_ilock (mbox, MU_LOCKER_WRLOCK); \
} \
} while (0)
#if 0
/* skip a function call, ?? do we gain that much */
#define ATTRIBUTE_CREATE(attr,mbox) \
#define ATTRIBUTE_CREATE(attr, m, mbox) \
do \
{ \
attr = calloc (1, sizeof(*(attr))); \
attr->owner = m; \
if ((attr) == NULL) \
{ \
mailbox_unix_iunlock (mbox); \
mailbox_unix_unlock (mbox); \
unix_iunlock (mbox); \
unix_unlock (mbox); \
return ENOMEM; \
} \
} while (0)
#else
# define ATTRIBUTE_CREATE
#endif
/* allocate slots for the new messages */
/* size_t num = 2 * ((mud)->messages_count) + 10; */
......@@ -269,38 +274,37 @@ do \
{ \
if ((mud)->messages_count >= (mud)->umessages_count) \
{ \
mailbox_unix_message_t *m; \
unix_message_t *m; \
size_t num = ((mud)->umessages_count) + 1; \
m = realloc ((mud)->umessages, num * sizeof (*m)); \
if (m == NULL) \
{ \
mailbox_unix_iunlock (mbox); \
mailbox_unix_unlock (mbox); \
unix_iunlock (mbox); \
unix_unlock (mbox); \
return ENOMEM; \
} \
(mud)->umessages = m; \
(mud)->umessages[num - 1] = calloc (1, sizeof (*(mum))); \
if ((mud)->umessages[num - 1] == NULL) \
{ \
mailbox_unix_iunlock (mbox); \
mailbox_unix_unlock (mbox); \
unix_iunlock (mbox); \
unix_unlock (mbox); \
return ENOMEM; \
} \
ATTRIBUTE_CREATE (((mud)->umessages[num - 1])->old_attr, mbox); \
(mud)->umessages_count = num; \
} \
} while (0)
static int
mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
{
#define MSGLINELEN 1024
char buf[MSGLINELEN];
int inheader;
int inbody;
off_t total = 0;
mailbox_unix_data_t mud;
mailbox_unix_message_t mum = NULL;
unix_data_t mud;
unix_message_t mum = NULL;
int status = 0;
size_t lines;
int newline;
......@@ -311,7 +315,7 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
/* sanity */
if (mbox == NULL ||
(mud = (mailbox_unix_data_t)mbox->data) == NULL)
(mud = (unix_data_t)mbox->data) == NULL)
return EINVAL;
/* save the timestamp and size */
......@@ -320,8 +324,8 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
return status;
/* grab the locks */
mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK);
mailbox_unix_lock (mbox, MU_LOCKER_RDLOCK);
unix_ilock (mbox, MU_LOCKER_WRLOCK);
unix_lock (mbox, MU_LOCKER_RDLOCK);
/* seek to the starting point */
if (mud->umessages && msgno > 0 && mud->messages_count > 0
......@@ -403,7 +407,7 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
/* every 50 mesgs update the lock, it should be every minute */
if ((mud->messages_count % 50) == 0)
mailbox_unix_touchlock (mbox);
unix_touchlock (mbox);
/* ping them every 1000 lines */
if (do_notif)
......@@ -419,8 +423,8 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif)
if (do_notif)
DISPATCH_ADD_MSG(mbox, mud);
}
mailbox_unix_iunlock (mbox);
mailbox_unix_unlock (mbox);
unix_iunlock (mbox);
unix_unlock (mbox);
if (pcount)
*pcount = mud->messages_count;
return status;
......
......@@ -68,7 +68,7 @@ message_destroy (message_t *pmsg, void *owner)
/* header */
header_destroy (&(msg->header), owner);
/* attribute */
attribute_destroy (&(msg->attribute));
attribute_destroy (&(msg->attribute), owner);
/* stream */
stream_destroy (&(msg->stream), owner);
......@@ -325,7 +325,7 @@ message_get_attribute (message_t msg, attribute_t *pattribute)
if (msg->attribute == NULL)
{
attribute_t attribute;
int status = attribute_create (&attribute);
int status = attribute_create (&attribute, msg);
if (status != 0)
return status;
msg->attribute = attribute;
......@@ -341,7 +341,7 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner)
return EINVAL;
if (msg->owner != owner)
return EACCES;
attribute_destroy (&(msg->attribute));
attribute_destroy (&(msg->attribute), owner);
msg->attribute = attribute;
return 0;
}
......@@ -532,7 +532,11 @@ message_read (stream_t is, char *buf, size_t buflen,
header_size (msg->header, &hsize);
body_size (msg->body, &bsize);
if ((size_t)off <= hsize)
/* On some remote sever (POP) the size of the header and body is not known
until you start reading them. So by checking hsize == bsize == 0, we
This kludge of a way of detecting the anomalie and start by the
header. */
if ((size_t)off <= hsize || (hsize == 0 && bsize == 0))
{
header_get_stream (msg->header, &his);
stream_read (his, buf, buflen, off, &hread);
......
......@@ -25,13 +25,12 @@
#include <string.h>
#include <errno.h>
/*
Builtin mailbox types.
A circular list is use for the builtin.
/* Builtin mailbox types. A circular list is use for the builtin.
Proper locking is not done when accessing the list.
FIXME: not thread-safe. */
static struct _registrar registrar [] = {
static struct _registrar registrar [] =
{
{ NULL, NULL, 0, &registrar[1] }, /* sentinel, head list */
{ &_url_file_registrar, &_mailbox_mbox_registrar, 0, &registrar[2] },
{ &_url_mbox_registrar, &_mailbox_mbox_registrar, 0, &registrar[3] },
......