Commit bbbdd3d8 bbbdd3d8f2b51a3e9ec0bbc4af756fe4291c4789 by Alain Magloire

message_t is a general structure that encapsulate envelope_t, header_t and

body_t etc ...
Accessing member of the structure is thread-safe, a monitor/lock is use
the downside the lock is grab for each modification.
1 parent 87eccb42
@code{#include <mailutils/message.h>}
The @code{message_t} object is a convenient way to manipulate messages. It
encapsulates the @code{header_t}, the @code{attribute_t} and the @code{body_t}.
encapsulates the @code{envelope_t}, the @code{header_t} and the @code{body_t}.
@example
@group
__________ message_t
(message[1]) +------>+-----------------------+
---------- | | header_t |
---------- | | envelope_t |
(message[2]) | |-----------------------|
---------- | | attribute_t |
---------- | | header_t |
(message[3])--------+ |-----------------------|
---------- | stream_t |
(message[n]) |-----------------------|
---------- | body_t |
(message[n]) |-----------------------|
---------- | attribute_t |
|-----------------------|
| from |
| stream_t |
|-----------------------|
| size |
|-----------------------|
......@@ -78,10 +78,10 @@ Return non-zero value if message is multi-part.
@deftypefun int message_set_attribute (message_t @var{msg}, attribute_t @var{attribute}, void *owner)
@end deftypefun
@deftypefun int message_get_from (message_t @var{msg}, char *buffer, size_t len, size_t *n)
@deftypefun int message_get_envelope (message_t @var{msg}, envelope_t *penvelope)
@end deftypefun
@deftypefun int message_set_from (message_t @var{msg}, int (*@var{_from}) (message_t, char *, size_t, size_t *), void *@var{owner})
@deftypefun int message_set_envelope (message_t @var{msg}, envelope_t envelope, void *@var{owner})
@end deftypefun
@deftypefun int message_get_uidl (message_t @var{msg}, char *@var{buffer}, size_t @var{buflen}, size_t *@var{pwriten})
......
......@@ -5,6 +5,7 @@ pkginclude_HEADERS = \
auth.h \
body.h \
debug.h \
envelope.h \
folder.h \
header.h \
iterator.h \
......@@ -14,6 +15,7 @@ pkginclude_HEADERS = \
mailer.h \
message.h \
mime.h \
monitor.h \
observer.h \
registrar.h \
stream.h \
......
/* 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. */
#ifndef _MAILUTILS_ENVELOPE_H
# define _MAILUTILS_ENVELOPE_H
#include <sys/types.h>
#ifdef __cplusplus
extern "C" { /*}*/
#endif
#ifndef __P
# ifdef __STDC__
# define __P(args) args
# else
# define __P(args) ()
# endif
#endif /*__P */
struct _envelope;
typedef struct _envelope *envelope_t;
int envelope_create (envelope_t *, void *);
void envelope_destroy (envelope_t *, void *);
void * envelope_get_owner (envelope_t);
int envelope_set_from (envelope_t, int (*_from) __P ((envelope_t, char *, size_t, size_t*)), void *);
int envelope_from (envelope_t, char *, size_t, size_t *);
int envelope_set_date (envelope_t, int (*_date) __P ((envelope_t, char *, size_t , size_t *)), void *);
int envelope_date (envelope_t, char *, size_t, size_t *);
#endif /* _MAILUTILS_ENVELOPE_H */
......@@ -53,7 +53,7 @@ extern int folder_close __P ((folder_t));
extern int folder_delete_mailbox __P ((folder_t, const char *));
extern int folder_list __P ((folder_t, list_t *list));
extern int folder_list __P ((folder_t, char *vector[][], size_t *));
/* Stream settings. */
extern int folder_get_stream __P ((folder_t, stream_t *));
......
......@@ -19,11 +19,13 @@
#define _MAILUTILS_MESSAGE_H
#include <sys/types.h>
#include <mailutils/stream.h>
#include <mailutils/envelope.h>
#include <mailutils/header.h>
#include <mailutils/body.h>
#include <mailutils/stream.h>
#include <mailutils/observer.h>
#include <mailutils/attribute.h>
#include <mailutils/monitor.h>
#ifndef __P
......@@ -53,6 +55,9 @@ extern void * message_get_owner __P ((message_t));
extern int message_ref __P ((message_t));
#define message_unref(msg) message_destroy (&msg, NULL)
extern int message_get_envelope __P ((message_t, envelope_t *));
extern int message_set_envelope __P ((message_t, envelope_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));
......@@ -81,16 +86,6 @@ 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_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 *)),
......
......@@ -245,7 +245,7 @@ main (int argc, char **argv)
{
int len;
free (command);
command = readline (prompt->set && prompt->value != NULL ? prompt->value : "");
command = readline (prompt->set && prompt->value != NULL ? prompt->value : " ");
len = strlen (command);
while (command[len-1] == '\\')
{
......
......@@ -19,6 +19,7 @@ auth.c \
bio.c \
body.c \
debug.c \
envelope.c \
file_stream.c \
folder.c \
header.c \
......@@ -35,6 +36,7 @@ mbx_pop.c \
message.c \
mime.c \
misc.c
monitor.c
observer.c \
registrar.c \
sendmail.c \
......
/* 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 <errno.h>
#include <stdlib.h>
#include <envelope0.h>
int
envelope_create (envelope_t *penvelope, void *owner)
{
envelope_t envelope;
if (penvelope == NULL)
return EINVAL;
envelope = calloc (1, sizeof (*envelope));
if (envelope == NULL)
return ENOMEM;
envelope->owner = owner;
*penvelope = envelope;
return 0;
}
void
envelope_destroy (envelope_t *penvelope, void *owner)
{
if (penvelope && *penvelope)
{
envelope_t envelope = *penvelope;
if (envelope->owner == owner)
{
if (envelope->_destroy)
envelope->_destroy (envelope);
free (envelope);
}
*penvelope = NULL;
}
}
void *
envelope_get_owner (envelope_t envelope)
{
return (envelope) ? envelope->owner : NULL;
}
int
envelope_set_from (envelope_t envelope,
int (*_from) __P ((envelope_t, char *, size_t, size_t*)),
void *owner)
{
if (envelope == NULL)
return EINVAL;
if (envelope->owner != owner)
return EACCES;
envelope->_from = _from;
return 0;
}
int
envelope_from (envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
{
if (envelope == NULL)
return EINVAL;
if (envelope->_from)
return envelope->_from (envelope, buf, len, pnwrite);
if (buf && len)
*buf = '\0';
if (pnwrite)
*pnwrite = 0;
return 0;
}
int
envelope_set_date (envelope_t envelope,
int (*_date) __P ((envelope_t, char *, size_t , size_t *)),
void *owner)
{
if (envelope == NULL)
return EINVAL;
if (envelope->owner != owner)
return EACCES;
envelope->_date = _date;
return 0;
}
int
envelope_date (envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
{
if (envelope == NULL)
return EINVAL;
if (envelope->_date)
return envelope->_date (envelope, buf, len, pnwrite);
if (buf && len)
*buf = '\0';
if (pnwrite)
*pnwrite = 0;
return 0;
}
......@@ -165,23 +165,19 @@ folder_destroy (folder_t *pfolder)
folder_t folder = *pfolder;
int destroy_lock = 0;
monitor_t monitor = folder->monitor;
size_t reference;
monitor_wrlock (monitor);
#ifdef WITH_PTHREAD
pthread_mutex_lock (&slock);
#endif
{
folder->ref--;
reference = folder->ref;
/* Remove the folder from the list of known folder. */
if (reference == 0)
if (folder->ref <= 0)
list_remove (known_folder_list, folder);
}
#ifdef WITH_PHTREAD
pthread_mutex_unlock (&slock);
#endif
if (reference == 0)
if (folder->ref <= 0)
{
monitor_unlock (monitor);
destroy_lock = 1;
......@@ -328,13 +324,12 @@ folder_get_debug (folder_t folder, debug_t *pdebug)
return 0;
}
int
folder_list (folder_t folder, list_t *plist)
folder_list (folder_t folder, char *vector[][], size_t *pnum)
{
if (folder == NULL || folder->_list == NULL)
return ENOSYS;
return folder->_list (folder, plist);
return folder->_list (folder, vector, pnum);
}
int
......@@ -380,7 +375,7 @@ static int is_known_folder (url_t url, folder_t *pfolder)
static int
is_same_scheme (url_t url1, url_t url2)
{
int i = 0, j = 0;
size_t i = 0, j = 0;
char *s1, *s2;
int ret = 1;
......@@ -405,7 +400,7 @@ is_same_scheme (url_t url1, url_t url2)
static int
is_same_user (url_t url1, url_t url2)
{
int i = 0, j = 0;
size_t i = 0, j = 0;
char *s1, *s2;
int ret = 0;
......@@ -430,7 +425,7 @@ is_same_user (url_t url1, url_t url2)
static int
is_same_path (url_t url1, url_t url2)
{
int i = 0, j = 0;
size_t i = 0, j = 0;
char *s1, *s2;
int ret = 0;
......@@ -455,7 +450,7 @@ is_same_path (url_t url1, url_t url2)
static int
is_same_host (url_t url1, url_t url2)
{
int i = 0, j = 0;
size_t i = 0, j = 0;
char *s1, *s2;
int ret = 0;
......
......@@ -5,6 +5,7 @@ auth0.h \
bio.h \
body0.h \
debug0.h \
envelope0.h \
folder0.h \
header0.h \
iterator0.h \
......@@ -14,6 +15,7 @@ mailer0.h \
message0.h \
mime0.h \
misc.h \
monitor0.h \
observer0.h \
registrar0.h \
stream0.h \
......
/* 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. */
#ifndef _ENVELOPE0_H
#define _ENVELOPE0_H
#ifdef DMALLOC
#include <dmalloc.h>
#endif
#include <mailutils/envelope.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __P
# ifdef __STDC__
# define __P(args) args
# else
# define __P(args) ()
# endif
#endif /*__P */
struct _envelope
{
void *owner;
int (*_destroy) __P ((envelope_t));
int (*_from) __P ((envelope_t, char *, size_t, size_t*));
int (*_date) __P ((envelope_t, char *, size_t , size_t *));
};
#endif /* _ENVELOPE0_H */
......@@ -51,7 +51,7 @@ struct _folder
monitor_t monitor;
url_t url;
int flags;
size_t ref;
int ref;
size_t uid;
/* Back pointer to the specific mailbox */
......@@ -64,7 +64,7 @@ struct _folder
int (*_open) __P ((folder_t, int flag));
int (*_close) __P ((folder_t));
int (*_list) __P ((folder_t, list_t *));
int (*_list) __P ((folder_t, char *vector[][], size_t *num));
int (*_delete_mailbox) __P ((folder_t, const char *));
};
......
......@@ -45,10 +45,13 @@ struct _message
/* Who is the owner. */
void *owner;
envelope_t envelope;
header_t header;
stream_t stream;
body_t body;
stream_t stream;
attribute_t attribute;
monitor_t monitor;
mime_t mime;
observable_t observable;
......@@ -60,8 +63,6 @@ struct _message
size_t hdr_buflen;
int hdr_done;
int (*_from) __P ((message_t, char *, size_t, size_t *));
int (*_received) __P ((message_t, char *, size_t, size_t *));
int (*_get_uidl) __P ((message_t, char *, size_t, size_t *));
int (*_get_num_parts) __P ((message_t, size_t *));
int (*_get_part) __P ((message_t, size_t, message_t *));
......
......@@ -162,8 +162,8 @@ static int mbox_header_size (header_t, size_t *);
static int mbox_header_lines (header_t, size_t *);
static int mbox_body_size (body_t, size_t *);
static int mbox_body_lines (body_t, size_t *);
static int mbox_msg_from (message_t, char *, size_t, size_t *);
static int mbox_msg_received (message_t, char *, size_t, size_t *);
static int mbox_envelope_from (envelope_t, char *, size_t, size_t *);
static int mbox_envelope_date (envelope_t, char *, size_t, size_t *);
static void mbox_cleanup (void *);
/* We allocate the mbox_data_t struct, but don't do any parsing on the name or
......@@ -981,9 +981,10 @@ mbox_body_lines (body_t body, size_t *plines)
}
static int
mbox_msg_received (message_t msg, char *buf, size_t len,
mbox_envelope_date (envelope_t envelope, char *buf, size_t len,
size_t *pnwrite)
{
message_t msg = envelope_get_owner (envelope);
mbox_message_t mum = message_get_owner (msg);
size_t n = 0;
int status;
......@@ -1026,8 +1027,10 @@ mbox_msg_received (message_t msg, char *buf, size_t len,
}
static int
mbox_msg_from (message_t msg, char *buf, size_t len, size_t *pnwrite)
mbox_envelope_from (envelope_t envelope, char *buf, size_t len,
size_t *pnwrite)
{
message_t msg = envelope_get_owner (envelope);
mbox_message_t mum = message_get_owner (msg);
size_t n = 0;
int status;
......@@ -1158,8 +1161,18 @@ mbox_get_message (mailbox_t mailbox, size_t msgno, message_t *pmsg)
}
/* Set the envelope. */
message_set_from (msg, mbox_msg_from, mum);
message_set_received (msg, mbox_msg_received, mum);
{
envelope_t envelope= NULL;
status = envelope_create (&envelope, msg);
if (status != 0)
{
message_destroy (&msg, mum);
return status;
}
envelope_set_from (envelope, mbox_envelope_from, msg);
envelope_set_date (envelope, mbox_envelope_date, msg);
message_set_envelope (msg, envelope, mum);
}
/* Attach the message to the mailbox mbox data. */
mum->message = msg;
......@@ -1229,7 +1242,9 @@ mbox_append_message (mailbox_t mailbox, message_t msg)
{
char *s;
size_t len = 0;
status = message_from (msg, mud->from, 127, &len);
envelope_t envelope;
message_get_envelope (msg, &envelope);
status = envelope_from (envelope, mud->from, 127, &len);
if (status != 0)
{
if (status != EAGAIN)
......@@ -1255,7 +1270,9 @@ mbox_append_message (mailbox_t mailbox, message_t msg)
{
char *s;
size_t len = 0;
status = message_received (msg, mud->date, 127, &len);
envelope_t envelope;
message_get_envelope (msg, &envelope);
status = envelope_date (envelope, mud->date, 127, &len);
if (status != 0)
{
if (status != EAGAIN)
......
......@@ -352,7 +352,7 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif)
mum->mud = mud;
mum->header_from = total - n;
mum->header_from_end = total;
mum->body_end = 0;
mum->body_end = mum->body = 0;
lines = 0;
}
else if ((n > 7) && ISSTATUS(buf))
......
......@@ -196,7 +196,7 @@ do \
|| (mpd->id && mpd->id != (size_t)identity)) \
{ \
mpd->id = 0; \
mpd->func = pop_open; \
mpd->func = (void *)pop_open; \
mpd->state = POP_NO_STATE; \
monitor_unlock (mbox->monitor); \
err = pop_open (mbox, mbox->flags); \
......
......@@ -21,8 +21,8 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <time.h>
#include <unistd.h>
#include <mailutils/message.h>
#include <mailutils/stream.h>
......@@ -217,7 +217,7 @@ static void _mime_append_header_line(mime_t mime)
static int _mime_parse_mpart_message(mime_t mime)
{
char *cp, *cp2;
int blength, body_length, body_offset, body_lines, ret;
int blength, mb_length, mb_offset, mb_lines, ret;
size_t nbytes;
if ( !(mime->flags & MIME_PARSER_ACTIVE) ) {
......@@ -237,9 +237,9 @@ static int _mime_parse_mpart_message(mime_t mime)
mime->parser_state = MIME_STATE_SCAN_BOUNDARY;
mime->flags |= MIME_PARSER_ACTIVE;
}
body_length = mime->body_length;
body_offset = mime->body_offset;
body_lines = mime->body_lines;
mb_length = mime->body_length;
mb_offset = mime->body_offset;
mb_lines = mime->body_lines;
while ( ( ret = stream_read(mime->stream, mime->cur_buf, mime->buf_size, mime->cur_offset, &nbytes) ) == 0 && nbytes ) {
cp = mime->cur_buf;
......@@ -256,15 +256,15 @@ static int _mime_parse_mpart_message(mime_t mime)
cp2 = mime->cur_line[0] == '\n' ? mime->cur_line + 1 : mime->cur_line;
blength = strlen(mime->boundary);
if ( mime->header_length )
body_lines++;
mb_lines++;
if ( mime->line_ndx >= blength ) {
if ( ( !strncasecmp(cp2,"--", 2) && !strncasecmp(cp2+2, mime->boundary, blength) )
|| !strncasecmp(cp2, mime->boundary, blength) ) {
mime->parser_state = MIME_STATE_HEADERS;
mime->flags &= ~MIME_PARSER_HAVE_CR;
body_length = mime->cur_offset - body_offset - mime->line_ndx + 1;
mb_length = mime->cur_offset - mb_offset - mime->line_ndx + 1;
if ( mime->header_length ) /* this skips the preamble */
_mime_append_part(mime, NULL, body_offset, body_length, body_lines);
_mime_append_part(mime, NULL, mb_offset, mb_length, mb_lines);
if ( ( cp2 + blength + 2 < cp && !strncasecmp(cp2+2+blength, "--",2) ) ||
!strncasecmp(cp2+blength, "--",2) ) { /* very last boundary */
mime->parser_state = MIME_STATE_BEGIN_LINE;
......@@ -283,8 +283,8 @@ static int _mime_parse_mpart_message(mime_t mime)
_mime_append_header_line(mime);
if ( mime->line_ndx == 1 || mime->cur_line[0] == '\r' ) {
mime->parser_state = MIME_STATE_BEGIN_LINE;
body_offset = mime->cur_offset + 1;
body_lines = 0;
mb_offset = mime->cur_offset + 1;
mb_lines = 0;
}
mime->line_ndx = -1;
break;
......@@ -300,12 +300,12 @@ static int _mime_parse_mpart_message(mime_t mime)
cp++;
}
}
mime->body_lines = body_lines;
mime->body_length = body_length;
mime->body_offset = body_offset;
mime->body_lines = mb_lines;
mime->body_length = mb_length;
mime->body_offset = mb_offset;
if ( ret != EAGAIN ) { /* finished cleanup */
if ( mime->header_length ) /* this skips the preamble */
_mime_append_part(mime, NULL, body_offset, body_length, body_lines);
_mime_append_part(mime, NULL, mb_offset, mb_length, mb_lines);
mime->flags &= ~MIME_PARSER_ACTIVE;
mime->body_offset = mime->body_length = mime->header_length = mime->body_lines = 0;
}
......@@ -382,7 +382,7 @@ static int _mime_set_content_type(mime_t mime)
else
strcpy(content_type, "multipart/alternative; boundary=");
if ( mime->boundary == NULL ) {
sprintf (boundary,"%ld-%ld=:%ld",random (),time (0), getpid ());
sprintf (boundary,"%ld-%ld=:%ld",(long)random (), (long)time (0), (long)getpid ());
if ( ( mime->boundary = strdup(boundary) ) == NULL )
return ENOMEM;
}
......@@ -465,9 +465,12 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off,
return 0;
message_get_stream(mime->mtp_parts[mime->cur_part]->msg, &msg_stream);
} else {
body_t b;
message_get_body(mime->mtp_parts[mime->cur_part]->msg, &b);
body_get_stream(b, &msg_stream);
body_t part_body;
if ( mime->cur_part >= mime->nmtp_parts )
return 0;
message_get_body(mime->mtp_parts[mime->cur_part]->msg, &part_body);
body_get_stream(part_body, &msg_stream);
}
ret = stream_read(msg_stream, buf, buflen, mime->part_offset, &part_nbytes );
len += part_nbytes;
......@@ -475,11 +478,11 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off,
if ( nbytes )
*nbytes += len;
mime->cur_offset += len;
if ( ret == 0 && part_nbytes == 0 && mime->nmtp_parts > 1 ) {
if ( ret == 0 && part_nbytes == 0 ) {
mime->flags |= MIME_INSERT_BOUNDARY;
mime->cur_part++;
}
} while( ret == 0 && part_nbytes == 0 && mime->cur_part < mime->nmtp_parts );
} while( ret == 0 && part_nbytes == 0 && mime->cur_part <= mime->nmtp_parts );
}
return ret;
}
......
......@@ -140,6 +140,7 @@ parseaddr (const char *addr, char *buf, size_t bufsz)
struct token *t, *tok, *last;
struct token *brace = NULL;
int comment = 0;
int status = 0;
tok = last = NULL;
......@@ -171,7 +172,10 @@ parseaddr (const char *addr, char *buf, size_t bufsz)
for (; t && t->word[0] != ',' && t->word[0] != '>'; t = t->next)
{
if (strlen (t->word) >= bufsz)
return -1;
{
status = -1;
break;
}
bufsz -= strlen (t->word);
strcat (buf, t->word);
}
......@@ -183,5 +187,5 @@ parseaddr (const char *addr, char *buf, size_t bufsz)
free (t);
}
return 0;
return status;
}
......
......@@ -33,7 +33,6 @@
#include <mailer0.h>
#include <registrar0.h>
#include <bio.h>
#include <misc.h>
static int smtp_init (mailer_t);
......