Commit 4e0913bf 4e0913bf210cabf46e36866617158ef96ca90a91 by Alain Magloire

The big change: For getting the header we use "TOP # 0" but since TOP is an

optionnal command, we fallback to RETR and ignore the body part.  This ugly
and wastefull and it made the code unnecessary complexe.  But fortunately
I do not know of any POP server that does not have TOP. It's a mess.
The other stuff was little cleanups.
1 parent 526e7396
The current maintainer Alain Magloire <alainm@rcsm.ece.mcgill.ca>
The current maintainer Alain Magloire <alainm@gnu.org>
Brian Edmond <briane@qnx.com>
Dave Inglis <dinglis@qnx.com>
Jakob Kaivo <jkaivo@ndn.net>
Jeff Bailey <jbailey@gnu.org>
Sean 'Shaleh' Perry <shaleh@debian.org>
......
2000--5-19 Sean 'Shaleh' Perry <shaleh@debian.org>
2000-09-01 Alain Magloire
*
2000-5-19 Sean 'Shaleh' Perry <shaleh@debian.org>
* libmailbox/mh.c: fleshed out mh_open() some more
......
......@@ -47,13 +47,11 @@ extern int body_get_filename __P ((body_t, char *, size_t, size_t *));
extern int body_set_filename __P ((body_t, const char*));
extern int body_size __P ((body_t, size_t*));
extern int body_set_size __P ((body_t,
int (*_size) __P ((body_t, size_t*)),
void *owner));
extern int body_set_size __P ((body_t, int (*_size)
__P ((body_t, size_t*)), void *owner));
extern int body_lines __P ((body_t, size_t *));
extern int body_set_lines __P ((body_t,
int (*_lines) __P ((body_t, size_t*)),
void *owner));
extern int body_set_lines __P ((body_t, int (*_lines)
__P ((body_t, size_t*)), void *owner));
#ifdef _cplusplus
}
......
......@@ -70,24 +70,29 @@ typedef struct _header * header_t;
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_set_set_value __P ((header_t, int (*_set_value)
__P ((header_t, const char *,
const char *, int)), void *));
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_get_value __P ((header_t, int (*_get_value)
__P ((header_t, const char *, char *,
size_t, size_t *)), void *));
extern int header_get_stream __P ((header_t, stream_t *));
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 *,
char *, size_t, size_t *)),
void *));
extern int header_size __P ((header_t, size_t *));
extern int header_set_size __P ((header_t, int (*_size)
__P ((header_t, size_t *)), void *));
extern int header_lines __P ((header_t, size_t *));
extern int header_set_lines __P ((header_t, int (*_lines)
__P ((header_t, size_t *)), void *));
#ifdef _cplusplus
}
......
......@@ -45,49 +45,59 @@ typedef struct _message *message_t;
* header_t, body_t, and its attribute_t.
*/
extern int message_create __P ((message_t *, void *owner));
extern void message_destroy __P ((message_t *, void *owner));
extern int message_get_header __P ((message_t, header_t *));
extern int message_set_header __P ((message_t, header_t, void *owner));
extern int message_get_body __P ((message_t, body_t *));
extern int message_set_body __P ((message_t, body_t, void *owner));
extern int message_get_stream __P ((message_t, stream_t *));
extern int message_is_mime __P ((message_t));
extern int message_size __P ((message_t, size_t *));
extern int message_lines __P ((message_t, size_t *));
extern int message_from __P ((message_t, char *, size_t, size_t *));
extern int message_set_from __P ((message_t,
int (*_from) __P ((message_t, char *,
size_t, size_t *)),
void *owner));
extern int message_received __P ((message_t, char *, size_t, size_t *));
extern int message_set_received __P ((message_t, int (*_received)
__P ((message_t, char *, size_t,
size_t *)), void *owner));
extern int message_get_attribute __P ((message_t, attribute_t *));
extern int message_set_attribute __P ((message_t, attribute_t, void *owner));
extern int message_get_num_parts __P ((message_t, size_t *nparts));
extern int message_set_get_num_parts __P ((message_t, int (*_getNum_parts)
__P ((message_t, size_t *)),
void *owner));
extern int message_get_part __P ((message_t, size_t part, message_t *msg));
extern int message_set_get_part __P ((message_t, int (*_get_part)
__P ((message_t, size_t, message_t *)),
void *owner));
extern int message_get_uidl __P ((message_t, char *buffer, size_t, size_t *));
extern int message_set_uidl __P ((message_t, int (*_get_uidl)
__P ((message_t, char *, size_t, size_t *)),
void *owner));
extern int message_create __P ((message_t *, void *owner));
extern void message_destroy __P ((message_t *, void *owner));
extern int message_get_header __P ((message_t, header_t *));
extern int message_set_header __P ((message_t, header_t, void *owner));
extern int message_get_body __P ((message_t, body_t *));
extern int message_set_body __P ((message_t, body_t, void *owner));
extern int message_get_stream __P ((message_t, stream_t *));
extern int message_set_stream __P ((message_t, stream_t, void *owner));
extern int message_is_multipart __P ((message_t, int *));
extern int message_set_is_multipart __P ((message_t, int (*_is_multipart)
__P ((message_t, int *)), void *));
extern int message_size __P ((message_t, size_t *));
extern int message_set_size __P ((message_t, int (*_size)
__P ((message_t, size_t *)),
void *owner));
extern int message_lines __P ((message_t, size_t *));
extern int message_set_lines __P ((message_t, int (*_lines)
__P ((message_t, size_t *)),
void *owner));
extern int message_from __P ((message_t, char *, size_t, size_t *));
extern int message_set_from __P ((message_t, int (*_from)
__P ((message_t, char *, size_t,
size_t *)), void *owner));
extern int message_received __P ((message_t, char *, size_t, size_t *));
extern int message_set_received __P ((message_t, int (*_received)
__P ((message_t, char *, size_t,
size_t *)), void *owner));
extern int message_get_attribute __P ((message_t, attribute_t *));
extern int message_set_attribute __P ((message_t, attribute_t, void *));
extern int message_get_num_parts __P ((message_t, size_t *nparts));
extern int message_set_get_num_parts __P ((message_t, int (*_get_num_parts)
__P ((message_t, size_t *)),
void *owner));
extern int message_get_part __P ((message_t, size_t, message_t *));
extern int message_set_get_part __P ((message_t, int (*_get_part)
__P ((message_t, size_t,
message_t *)), void *owner));
extern int message_get_uidl __P ((message_t, char *, size_t, size_t *));
extern int message_set_uidl __P ((message_t, int (*_get_uidl)
__P ((message_t, char *, size_t,
size_t *)), void *owner));
/* events */
#define MU_EVT_MSG_DESTROY 32
......
......@@ -198,7 +198,8 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
if (header == NULL || fn == NULL || fv == NULL)
return EINVAL;
if (header->_set_value != NULL)
/* Overload. */
if (header->_set_value)
return header->_set_value (header, fn, fv, replace);
/* Try to fill out the buffer, if we know how. */
......@@ -268,7 +269,8 @@ header_get_value (header_t header, const char *name, char *buffer,
if (header == NULL || name == NULL)
return EINVAL;
if (header->_get_value != NULL)
/* Overload. */
if (header->_get_value)
return header->_get_value (header, name, buffer, buflen, pn);
/* Try to fill out the buffer, if we know how. */
......@@ -320,27 +322,36 @@ header_get_value (header_t header, const char *name, char *buffer,
if (pn)
*pn = total;
/* Check if they provided a hook. */
if (total == 0)
{
err = ENOENT;
if (header->_get_value != NULL)
err = header->_get_value (header, name, buffer, buflen, pn);
/* Success. Cache it locally. */
if (err == 0)
header_set_value (header, name, buffer, 0);
}
err = ENOENT;
return err;
}
int
header_set_lines (header_t header, int (*_lines)
(header_t, size_t *), void *owner)
{
if (header == NULL)
return EINVAL;
if (header->owner != owner)
return EACCES;
header->_lines = _lines;
return 0;
}
int
header_lines (header_t header, size_t *plines)
{
int n;
size_t lines = 0;
if (header == NULL)
if (header == NULL || plines == NULL)
return EINVAL;
/* Overload. */
if (header->_lines)
return header->_lines (header, plines);
/* Try to fill out the buffer, if we know how. */
if (header->blurb == NULL)
{
......@@ -360,11 +371,27 @@ header_lines (header_t header, size_t *plines)
}
int
header_size (header_t header, size_t *pnum)
header_set_size (header_t header, int (*_size)
(header_t, size_t *), void *owner)
{
if (header == NULL)
return EINVAL;
if (header->owner != owner)
return EACCES;
header->_size = _size;
return 0;
}
int
header_size (header_t header, size_t *psize)
{
if (header == NULL)
return EINVAL;
/* Overload. */
if (header->_size)
return header->_size (header, psize);
/* Try to fill out the buffer, if we know how. */
if (header->blurb == NULL)
{
......@@ -373,8 +400,8 @@ header_size (header_t header, size_t *pnum)
return err;
}
if (pnum)
*pnum = header->blurb_len;
if (psize)
*psize = header->blurb_len;
return 0;
}
......
......@@ -43,6 +43,9 @@ mailbox_create (mailbox_t *pmbox, const char *name, int id)
struct mailbox_registrar *mreg;
url_t url = NULL;
if (pmbox == NULL)
return EINVAL;
url_create (&url, name);
/* 1st guest: if an ID is specify, shortcut */
......@@ -151,6 +154,14 @@ mailbox_scan (mailbox_t mbox, size_t msgno, size_t *pcount)
return mbox->_scan (mbox, msgno, pcount);
}
int
mailbox_size (mailbox_t mbox, off_t *psize)
{
if (mbox == NULL || mbox->_size == NULL)
return 0;
return mbox->_size (mbox, psize);
}
/* locking */
int
mailbox_set_locker (mailbox_t mbox, locker_t locker)
......
......@@ -153,6 +153,17 @@ message_set_body (message_t msg, body_t body, void *owner)
}
int
message_set_stream (message_t msg, stream_t stream, void *owner)
{
if (msg == NULL)
return EINVAL;
if (msg->owner != owner)
return EACCES;
msg->stream = stream;
return 0;
}
int
message_get_stream (message_t msg, stream_t *pstream)
{
if (msg == NULL || pstream == NULL)
......@@ -177,11 +188,26 @@ message_get_stream (message_t msg, stream_t *pstream)
}
int
message_set_lines (message_t msg, int (*_lines)
(message_t, size_t *), void *owner)
{
if (msg == NULL)
return EINVAL;
if (msg->owner != owner)
return EACCES;
msg->_lines = _lines;
return 0;
}
int
message_lines (message_t msg, size_t *plines)
{
size_t hlines, blines;
if (msg == NULL)
return EINVAL;
/* Overload */
if (msg->_lines)
return msg->_lines (msg, plines);
if (plines)
{
hlines = blines = 0;
......@@ -193,11 +219,26 @@ message_lines (message_t msg, size_t *plines)
}
int
message_set_size (message_t msg, int (*_size)
(message_t, size_t *), void *owner)
{
if (msg == NULL)
return EINVAL;
if (msg->owner != owner)
return EACCES;
msg->_size = _size;
return 0;
}
int
message_size (message_t msg, size_t *psize)
{
size_t hsize, bsize;
if (msg == NULL)
return EINVAL;
/* Overload ? */
if (msg->_size)
return msg->_size (msg, psize);
if (psize)
{
hsize = bsize = 0;
......@@ -235,14 +276,14 @@ message_from (message_t msg, char *buf, size_t len, size_t *pnwrite)
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, "FROM", NULL, 0, &n);
status = header_get_value (header, MU_HEADER_FROM, NULL, 0, &n);
if (status == 0 && n != 0)
{
char *from = calloc (1, n + 1);
char *addr;
header_get_value (header, "FROM", from, n + 1, NULL);
header_get_value (header, MU_HEADER_FROM, from, n + 1, NULL);
if (extract_addr (from, n, &addr, &n) == 0)
{
n = (n > len) ? len : n;
......@@ -258,6 +299,8 @@ message_from (message_t msg, char *buf, size_t len, size_t *pnwrite)
return 0;
}
}
else if (status == EAGAIN)
return status;
/* oops */
n = (7 > len) ? len: 7;
......@@ -374,16 +417,43 @@ message_set_uidl (message_t msg, int (* _get_uidl)
}
int
message_is_mime (message_t msg)
message_set_is_multipart (message_t msg, int (*_is_multipart)
__P ((message_t, int *)), void *owner)
{
if (msg == NULL)
return EINVAL;
if (msg->owner != owner)
return EACCES;
msg->_is_multipart = _is_multipart;
return 0;
}
int
message_is_multipart (message_t msg, int *p_is_mp)
{
header_t header;
int status;
size_t len = 0;
status = message_get_header(msg, &header);
if (status != 0)
return status;
status = header_get_value (header, "Mime-Version", NULL, 0, NULL);
return (status == 0);
if (msg == NULL || p_is_mp)
return EINVAL;
message_get_header(msg, &header);
status = header_get_value (header, "Content-Type", NULL, 0, &len);
if (status == 0)
{
char *content_type = calloc (len + 1, sizeof (char));
if (content_type == NULL)
return ENOMEM;
status = header_get_value (header, "Content-Type", content_type,
len, NULL);
*p_is_mp = strncasecmp ("multipart", content_type,
strlen ("multipart")) ? 0: 1;
free (content_type);
}
else
*p_is_mp = 0;
return status;
}
int
......@@ -422,6 +492,7 @@ message_get_part (message_t msg, size_t part, message_t *pmsg)
if (msg == NULL || pmsg == NULL)
return EINVAL;
/* Overload. */
if (msg->_get_part)
return msg->_get_part (msg, part, pmsg);
......@@ -518,12 +589,11 @@ static int
message_read (stream_t is, char *buf, size_t buflen,
off_t off, size_t *pnread )
{
message_t msg;
message_t msg = is->owner;
stream_t his, bis;
size_t hread, hsize, bread, bsize;
if (is == NULL || (msg = is->owner) == NULL)
if (msg == NULL)
return EINVAL;
bsize = hsize = bread = hread = 0;
......@@ -536,16 +606,10 @@ message_read (stream_t is, char *buf, size_t buflen,
until you start reading them. So by checking hsize == bsize == 0,
this kludge is a way of detecting the anomalie and start by the
header. */
if ((size_t)off <= hsize || (hsize == 0 && bsize == 0))
if ((size_t)off < hsize || (hsize == 0 && bsize == 0))
{
header_get_stream (msg->header, &his);
stream_read (his, buf, buflen, off, &hread);
/* still room left for some body, .. a pun ;-) */
if ((buflen - hread) > 0)
{
body_get_stream (msg->body, &bis);
stream_read (bis, buf + hread, buflen - hread, 0, &bread);
}
}
else
{
......