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
1 @code{#include <mailutils/message.h>} 1 @code{#include <mailutils/message.h>}
2 2
3 The @code{message_t} object is a convenient way to manipulate messages. It 3 The @code{message_t} object is a convenient way to manipulate messages. It
4 encapsulates the @code{header_t}, the @code{attribute_t} and the @code{body_t}. 4 encapsulates the @code{envelope_t}, the @code{header_t} and the @code{body_t}.
5 5
6 @example 6 @example
7 @group 7 @group
8 __________ message_t 8 __________ message_t
9 (message[1]) +------>+-----------------------+ 9 (message[1]) +------>+-----------------------+
10 ---------- | | header_t | 10 ---------- | | envelope_t |
11 (message[2]) | |-----------------------| 11 (message[2]) | |-----------------------|
12 ---------- | | attribute_t | 12 ---------- | | header_t |
13 (message[3])--------+ |-----------------------| 13 (message[3])--------+ |-----------------------|
14 ---------- | stream_t |
15 (message[n]) |-----------------------|
16 ---------- | body_t | 14 ---------- | body_t |
15 (message[n]) |-----------------------|
16 ---------- | attribute_t |
17 |-----------------------| 17 |-----------------------|
18 | from | 18 | stream_t |
19 |-----------------------| 19 |-----------------------|
20 | size | 20 | size |
21 |-----------------------| 21 |-----------------------|
...@@ -78,10 +78,10 @@ Return non-zero value if message is multi-part. ...@@ -78,10 +78,10 @@ Return non-zero value if message is multi-part.
78 @deftypefun int message_set_attribute (message_t @var{msg}, attribute_t @var{attribute}, void *owner) 78 @deftypefun int message_set_attribute (message_t @var{msg}, attribute_t @var{attribute}, void *owner)
79 @end deftypefun 79 @end deftypefun
80 80
81 @deftypefun int message_get_from (message_t @var{msg}, char *buffer, size_t len, size_t *n) 81 @deftypefun int message_get_envelope (message_t @var{msg}, envelope_t *penvelope)
82 @end deftypefun 82 @end deftypefun
83 83
84 @deftypefun int message_set_from (message_t @var{msg}, int (*@var{_from}) (message_t, char *, size_t, size_t *), void *@var{owner}) 84 @deftypefun int message_set_envelope (message_t @var{msg}, envelope_t envelope, void *@var{owner})
85 @end deftypefun 85 @end deftypefun
86 86
87 @deftypefun int message_get_uidl (message_t @var{msg}, char *@var{buffer}, size_t @var{buflen}, size_t *@var{pwriten}) 87 @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 = \ ...@@ -5,6 +5,7 @@ pkginclude_HEADERS = \
5 auth.h \ 5 auth.h \
6 body.h \ 6 body.h \
7 debug.h \ 7 debug.h \
8 envelope.h \
8 folder.h \ 9 folder.h \
9 header.h \ 10 header.h \
10 iterator.h \ 11 iterator.h \
...@@ -14,6 +15,7 @@ pkginclude_HEADERS = \ ...@@ -14,6 +15,7 @@ pkginclude_HEADERS = \
14 mailer.h \ 15 mailer.h \
15 message.h \ 16 message.h \
16 mime.h \ 17 mime.h \
18 monitor.h \
17 observer.h \ 19 observer.h \
18 registrar.h \ 20 registrar.h \
19 stream.h \ 21 stream.h \
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Library Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifndef _MAILUTILS_ENVELOPE_H
19 # define _MAILUTILS_ENVELOPE_H
20
21 #include <sys/types.h>
22
23 #ifdef __cplusplus
24 extern "C" { /*}*/
25 #endif
26
27 #ifndef __P
28 # ifdef __STDC__
29 # define __P(args) args
30 # else
31 # define __P(args) ()
32 # endif
33 #endif /*__P */
34
35 struct _envelope;
36 typedef struct _envelope *envelope_t;
37
38 int envelope_create (envelope_t *, void *);
39 void envelope_destroy (envelope_t *, void *);
40 void * envelope_get_owner (envelope_t);
41 int envelope_set_from (envelope_t, int (*_from) __P ((envelope_t, char *, size_t, size_t*)), void *);
42 int envelope_from (envelope_t, char *, size_t, size_t *);
43 int envelope_set_date (envelope_t, int (*_date) __P ((envelope_t, char *, size_t , size_t *)), void *);
44 int envelope_date (envelope_t, char *, size_t, size_t *);
45
46 #endif /* _MAILUTILS_ENVELOPE_H */
...@@ -53,7 +53,7 @@ extern int folder_close __P ((folder_t)); ...@@ -53,7 +53,7 @@ extern int folder_close __P ((folder_t));
53 53
54 extern int folder_delete_mailbox __P ((folder_t, const char *)); 54 extern int folder_delete_mailbox __P ((folder_t, const char *));
55 55
56 extern int folder_list __P ((folder_t, list_t *list)); 56 extern int folder_list __P ((folder_t, char *vector[][], size_t *));
57 57
58 /* Stream settings. */ 58 /* Stream settings. */
59 extern int folder_get_stream __P ((folder_t, stream_t *)); 59 extern int folder_get_stream __P ((folder_t, stream_t *));
......
...@@ -19,11 +19,13 @@ ...@@ -19,11 +19,13 @@
19 #define _MAILUTILS_MESSAGE_H 19 #define _MAILUTILS_MESSAGE_H
20 20
21 #include <sys/types.h> 21 #include <sys/types.h>
22 #include <mailutils/stream.h> 22 #include <mailutils/envelope.h>
23 #include <mailutils/header.h> 23 #include <mailutils/header.h>
24 #include <mailutils/body.h> 24 #include <mailutils/body.h>
25 #include <mailutils/stream.h>
25 #include <mailutils/observer.h> 26 #include <mailutils/observer.h>
26 #include <mailutils/attribute.h> 27 #include <mailutils/attribute.h>
28 #include <mailutils/monitor.h>
27 29
28 30
29 #ifndef __P 31 #ifndef __P
...@@ -53,6 +55,9 @@ extern void * message_get_owner __P ((message_t)); ...@@ -53,6 +55,9 @@ extern void * message_get_owner __P ((message_t));
53 extern int message_ref __P ((message_t)); 55 extern int message_ref __P ((message_t));
54 #define message_unref(msg) message_destroy (&msg, NULL) 56 #define message_unref(msg) message_destroy (&msg, NULL)
55 57
58 extern int message_get_envelope __P ((message_t, envelope_t *));
59 extern int message_set_envelope __P ((message_t, envelope_t, void *owner));
60
56 extern int message_get_header __P ((message_t, header_t *)); 61 extern int message_get_header __P ((message_t, header_t *));
57 extern int message_set_header __P ((message_t, header_t, void *owner)); 62 extern int message_set_header __P ((message_t, header_t, void *owner));
58 63
...@@ -81,16 +86,6 @@ extern int message_set_lines __P ((message_t, int (*_lines) ...@@ -81,16 +86,6 @@ extern int message_set_lines __P ((message_t, int (*_lines)
81 __P ((message_t, size_t *)), 86 __P ((message_t, size_t *)),
82 void *owner)); 87 void *owner));
83 88
84 extern int message_from __P ((message_t, char *, size_t, size_t *));
85 extern int message_set_from __P ((message_t, int (*_from)
86 __P ((message_t, char *, size_t,
87 size_t *)), void *owner));
88
89 extern int message_received __P ((message_t, char *, size_t, size_t *));
90 extern int message_set_received __P ((message_t, int (*_received)
91 __P ((message_t, char *, size_t,
92 size_t *)), void *owner));
93
94 extern int message_get_num_parts __P ((message_t, size_t *nparts)); 89 extern int message_get_num_parts __P ((message_t, size_t *nparts));
95 extern int message_set_get_num_parts __P ((message_t, int (*_get_num_parts) 90 extern int message_set_get_num_parts __P ((message_t, int (*_get_num_parts)
96 __P ((message_t, size_t *)), 91 __P ((message_t, size_t *)),
......
...@@ -245,7 +245,7 @@ main (int argc, char **argv) ...@@ -245,7 +245,7 @@ main (int argc, char **argv)
245 { 245 {
246 int len; 246 int len;
247 free (command); 247 free (command);
248 command = readline (prompt->set && prompt->value != NULL ? prompt->value : ""); 248 command = readline (prompt->set && prompt->value != NULL ? prompt->value : " ");
249 len = strlen (command); 249 len = strlen (command);
250 while (command[len-1] == '\\') 250 while (command[len-1] == '\\')
251 { 251 {
......
...@@ -19,6 +19,7 @@ auth.c \ ...@@ -19,6 +19,7 @@ auth.c \
19 bio.c \ 19 bio.c \
20 body.c \ 20 body.c \
21 debug.c \ 21 debug.c \
22 envelope.c \
22 file_stream.c \ 23 file_stream.c \
23 folder.c \ 24 folder.c \
24 header.c \ 25 header.c \
...@@ -35,6 +36,7 @@ mbx_pop.c \ ...@@ -35,6 +36,7 @@ mbx_pop.c \
35 message.c \ 36 message.c \
36 mime.c \ 37 mime.c \
37 misc.c 38 misc.c
39 monitor.c
38 observer.c \ 40 observer.c \
39 registrar.c \ 41 registrar.c \
40 sendmail.c \ 42 sendmail.c \
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Library Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #include <errno.h>
19 #include <stdlib.h>
20 #include <envelope0.h>
21
22 int
23 envelope_create (envelope_t *penvelope, void *owner)
24 {
25 envelope_t envelope;
26 if (penvelope == NULL)
27 return EINVAL;
28 envelope = calloc (1, sizeof (*envelope));
29 if (envelope == NULL)
30 return ENOMEM;
31 envelope->owner = owner;
32 *penvelope = envelope;
33 return 0;
34 }
35
36 void
37 envelope_destroy (envelope_t *penvelope, void *owner)
38 {
39 if (penvelope && *penvelope)
40 {
41 envelope_t envelope = *penvelope;
42 if (envelope->owner == owner)
43 {
44 if (envelope->_destroy)
45 envelope->_destroy (envelope);
46 free (envelope);
47 }
48 *penvelope = NULL;
49 }
50 }
51
52 void *
53 envelope_get_owner (envelope_t envelope)
54 {
55 return (envelope) ? envelope->owner : NULL;
56 }
57
58 int
59 envelope_set_from (envelope_t envelope,
60 int (*_from) __P ((envelope_t, char *, size_t, size_t*)),
61 void *owner)
62 {
63 if (envelope == NULL)
64 return EINVAL;
65 if (envelope->owner != owner)
66 return EACCES;
67 envelope->_from = _from;
68 return 0;
69 }
70
71 int
72 envelope_from (envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
73 {
74 if (envelope == NULL)
75 return EINVAL;
76 if (envelope->_from)
77 return envelope->_from (envelope, buf, len, pnwrite);
78 if (buf && len)
79 *buf = '\0';
80 if (pnwrite)
81 *pnwrite = 0;
82 return 0;
83 }
84
85 int
86 envelope_set_date (envelope_t envelope,
87 int (*_date) __P ((envelope_t, char *, size_t , size_t *)),
88 void *owner)
89 {
90 if (envelope == NULL)
91 return EINVAL;
92 if (envelope->owner != owner)
93 return EACCES;
94 envelope->_date = _date;
95 return 0;
96 }
97
98 int
99 envelope_date (envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
100 {
101 if (envelope == NULL)
102 return EINVAL;
103 if (envelope->_date)
104 return envelope->_date (envelope, buf, len, pnwrite);
105 if (buf && len)
106 *buf = '\0';
107 if (pnwrite)
108 *pnwrite = 0;
109 return 0;
110 }
...@@ -165,23 +165,19 @@ folder_destroy (folder_t *pfolder) ...@@ -165,23 +165,19 @@ folder_destroy (folder_t *pfolder)
165 folder_t folder = *pfolder; 165 folder_t folder = *pfolder;
166 int destroy_lock = 0; 166 int destroy_lock = 0;
167 monitor_t monitor = folder->monitor; 167 monitor_t monitor = folder->monitor;
168 size_t reference;
169 168
170 monitor_wrlock (monitor); 169 monitor_wrlock (monitor);
171 #ifdef WITH_PTHREAD 170 #ifdef WITH_PTHREAD
172 pthread_mutex_lock (&slock); 171 pthread_mutex_lock (&slock);
173 #endif 172 #endif
174 {
175 folder->ref--; 173 folder->ref--;
176 reference = folder->ref;
177 /* Remove the folder from the list of known folder. */ 174 /* Remove the folder from the list of known folder. */
178 if (reference == 0) 175 if (folder->ref <= 0)
179 list_remove (known_folder_list, folder); 176 list_remove (known_folder_list, folder);
180 }
181 #ifdef WITH_PHTREAD 177 #ifdef WITH_PHTREAD
182 pthread_mutex_unlock (&slock); 178 pthread_mutex_unlock (&slock);
183 #endif 179 #endif
184 if (reference == 0) 180 if (folder->ref <= 0)
185 { 181 {
186 monitor_unlock (monitor); 182 monitor_unlock (monitor);
187 destroy_lock = 1; 183 destroy_lock = 1;
...@@ -328,13 +324,12 @@ folder_get_debug (folder_t folder, debug_t *pdebug) ...@@ -328,13 +324,12 @@ folder_get_debug (folder_t folder, debug_t *pdebug)
328 return 0; 324 return 0;
329 } 325 }
330 326
331
332 int 327 int
333 folder_list (folder_t folder, list_t *plist) 328 folder_list (folder_t folder, char *vector[][], size_t *pnum)
334 { 329 {
335 if (folder == NULL || folder->_list == NULL) 330 if (folder == NULL || folder->_list == NULL)
336 return ENOSYS; 331 return ENOSYS;
337 return folder->_list (folder, plist); 332 return folder->_list (folder, vector, pnum);
338 } 333 }
339 334
340 int 335 int
...@@ -380,7 +375,7 @@ static int is_known_folder (url_t url, folder_t *pfolder) ...@@ -380,7 +375,7 @@ static int is_known_folder (url_t url, folder_t *pfolder)
380 static int 375 static int
381 is_same_scheme (url_t url1, url_t url2) 376 is_same_scheme (url_t url1, url_t url2)
382 { 377 {
383 int i = 0, j = 0; 378 size_t i = 0, j = 0;
384 char *s1, *s2; 379 char *s1, *s2;
385 int ret = 1; 380 int ret = 1;
386 381
...@@ -405,7 +400,7 @@ is_same_scheme (url_t url1, url_t url2) ...@@ -405,7 +400,7 @@ is_same_scheme (url_t url1, url_t url2)
405 static int 400 static int
406 is_same_user (url_t url1, url_t url2) 401 is_same_user (url_t url1, url_t url2)
407 { 402 {
408 int i = 0, j = 0; 403 size_t i = 0, j = 0;
409 char *s1, *s2; 404 char *s1, *s2;
410 int ret = 0; 405 int ret = 0;
411 406
...@@ -430,7 +425,7 @@ is_same_user (url_t url1, url_t url2) ...@@ -430,7 +425,7 @@ is_same_user (url_t url1, url_t url2)
430 static int 425 static int
431 is_same_path (url_t url1, url_t url2) 426 is_same_path (url_t url1, url_t url2)
432 { 427 {
433 int i = 0, j = 0; 428 size_t i = 0, j = 0;
434 char *s1, *s2; 429 char *s1, *s2;
435 int ret = 0; 430 int ret = 0;
436 431
...@@ -455,7 +450,7 @@ is_same_path (url_t url1, url_t url2) ...@@ -455,7 +450,7 @@ is_same_path (url_t url1, url_t url2)
455 static int 450 static int
456 is_same_host (url_t url1, url_t url2) 451 is_same_host (url_t url1, url_t url2)
457 { 452 {
458 int i = 0, j = 0; 453 size_t i = 0, j = 0;
459 char *s1, *s2; 454 char *s1, *s2;
460 int ret = 0; 455 int ret = 0;
461 456
......
...@@ -5,6 +5,7 @@ auth0.h \ ...@@ -5,6 +5,7 @@ auth0.h \
5 bio.h \ 5 bio.h \
6 body0.h \ 6 body0.h \
7 debug0.h \ 7 debug0.h \
8 envelope0.h \
8 folder0.h \ 9 folder0.h \
9 header0.h \ 10 header0.h \
10 iterator0.h \ 11 iterator0.h \
...@@ -14,6 +15,7 @@ mailer0.h \ ...@@ -14,6 +15,7 @@ mailer0.h \
14 message0.h \ 15 message0.h \
15 mime0.h \ 16 mime0.h \
16 misc.h \ 17 misc.h \
18 monitor0.h \
17 observer0.h \ 19 observer0.h \
18 registrar0.h \ 20 registrar0.h \
19 stream0.h \ 21 stream0.h \
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Library Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifndef _ENVELOPE0_H
19 #define _ENVELOPE0_H
20
21 #ifdef DMALLOC
22 #include <dmalloc.h>
23 #endif
24
25 #include <mailutils/envelope.h>
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30
31 #ifndef __P
32 # ifdef __STDC__
33 # define __P(args) args
34 # else
35 # define __P(args) ()
36 # endif
37 #endif /*__P */
38
39 struct _envelope
40 {
41 void *owner;
42 int (*_destroy) __P ((envelope_t));
43 int (*_from) __P ((envelope_t, char *, size_t, size_t*));
44 int (*_date) __P ((envelope_t, char *, size_t , size_t *));
45 };
46
47 #endif /* _ENVELOPE0_H */
...@@ -51,7 +51,7 @@ struct _folder ...@@ -51,7 +51,7 @@ struct _folder
51 monitor_t monitor; 51 monitor_t monitor;
52 url_t url; 52 url_t url;
53 int flags; 53 int flags;
54 size_t ref; 54 int ref;
55 size_t uid; 55 size_t uid;
56 56
57 /* Back pointer to the specific mailbox */ 57 /* Back pointer to the specific mailbox */
...@@ -64,7 +64,7 @@ struct _folder ...@@ -64,7 +64,7 @@ struct _folder
64 64
65 int (*_open) __P ((folder_t, int flag)); 65 int (*_open) __P ((folder_t, int flag));
66 int (*_close) __P ((folder_t)); 66 int (*_close) __P ((folder_t));
67 int (*_list) __P ((folder_t, list_t *)); 67 int (*_list) __P ((folder_t, char *vector[][], size_t *num));
68 int (*_delete_mailbox) __P ((folder_t, const char *)); 68 int (*_delete_mailbox) __P ((folder_t, const char *));
69 }; 69 };
70 70
......
...@@ -45,10 +45,13 @@ struct _message ...@@ -45,10 +45,13 @@ struct _message
45 /* Who is the owner. */ 45 /* Who is the owner. */
46 void *owner; 46 void *owner;
47 47
48 envelope_t envelope;
48 header_t header; 49 header_t header;
49 stream_t stream;
50 body_t body; 50 body_t body;
51
52 stream_t stream;
51 attribute_t attribute; 53 attribute_t attribute;
54 monitor_t monitor;
52 mime_t mime; 55 mime_t mime;
53 observable_t observable; 56 observable_t observable;
54 57
...@@ -60,8 +63,6 @@ struct _message ...@@ -60,8 +63,6 @@ struct _message
60 size_t hdr_buflen; 63 size_t hdr_buflen;
61 int hdr_done; 64 int hdr_done;
62 65
63 int (*_from) __P ((message_t, char *, size_t, size_t *));
64 int (*_received) __P ((message_t, char *, size_t, size_t *));
65 int (*_get_uidl) __P ((message_t, char *, size_t, size_t *)); 66 int (*_get_uidl) __P ((message_t, char *, size_t, size_t *));
66 int (*_get_num_parts) __P ((message_t, size_t *)); 67 int (*_get_num_parts) __P ((message_t, size_t *));
67 int (*_get_part) __P ((message_t, size_t, message_t *)); 68 int (*_get_part) __P ((message_t, size_t, message_t *));
......
...@@ -162,8 +162,8 @@ static int mbox_header_size (header_t, size_t *); ...@@ -162,8 +162,8 @@ static int mbox_header_size (header_t, size_t *);
162 static int mbox_header_lines (header_t, size_t *); 162 static int mbox_header_lines (header_t, size_t *);
163 static int mbox_body_size (body_t, size_t *); 163 static int mbox_body_size (body_t, size_t *);
164 static int mbox_body_lines (body_t, size_t *); 164 static int mbox_body_lines (body_t, size_t *);
165 static int mbox_msg_from (message_t, char *, size_t, size_t *); 165 static int mbox_envelope_from (envelope_t, char *, size_t, size_t *);
166 static int mbox_msg_received (message_t, char *, size_t, size_t *); 166 static int mbox_envelope_date (envelope_t, char *, size_t, size_t *);
167 static void mbox_cleanup (void *); 167 static void mbox_cleanup (void *);
168 168
169 /* We allocate the mbox_data_t struct, but don't do any parsing on the name or 169 /* 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) ...@@ -981,9 +981,10 @@ mbox_body_lines (body_t body, size_t *plines)
981 } 981 }
982 982
983 static int 983 static int
984 mbox_msg_received (message_t msg, char *buf, size_t len, 984 mbox_envelope_date (envelope_t envelope, char *buf, size_t len,
985 size_t *pnwrite) 985 size_t *pnwrite)
986 { 986 {
987 message_t msg = envelope_get_owner (envelope);
987 mbox_message_t mum = message_get_owner (msg); 988 mbox_message_t mum = message_get_owner (msg);
988 size_t n = 0; 989 size_t n = 0;
989 int status; 990 int status;
...@@ -1026,8 +1027,10 @@ mbox_msg_received (message_t msg, char *buf, size_t len, ...@@ -1026,8 +1027,10 @@ mbox_msg_received (message_t msg, char *buf, size_t len,
1026 } 1027 }
1027 1028
1028 static int 1029 static int
1029 mbox_msg_from (message_t msg, char *buf, size_t len, size_t *pnwrite) 1030 mbox_envelope_from (envelope_t envelope, char *buf, size_t len,
1031 size_t *pnwrite)
1030 { 1032 {
1033 message_t msg = envelope_get_owner (envelope);
1031 mbox_message_t mum = message_get_owner (msg); 1034 mbox_message_t mum = message_get_owner (msg);
1032 size_t n = 0; 1035 size_t n = 0;
1033 int status; 1036 int status;
...@@ -1158,8 +1161,18 @@ mbox_get_message (mailbox_t mailbox, size_t msgno, message_t *pmsg) ...@@ -1158,8 +1161,18 @@ mbox_get_message (mailbox_t mailbox, size_t msgno, message_t *pmsg)
1158 } 1161 }
1159 1162
1160 /* Set the envelope. */ 1163 /* Set the envelope. */
1161 message_set_from (msg, mbox_msg_from, mum); 1164 {
1162 message_set_received (msg, mbox_msg_received, mum); 1165 envelope_t envelope= NULL;
1166 status = envelope_create (&envelope, msg);
1167 if (status != 0)
1168 {
1169 message_destroy (&msg, mum);
1170 return status;
1171 }
1172 envelope_set_from (envelope, mbox_envelope_from, msg);
1173 envelope_set_date (envelope, mbox_envelope_date, msg);
1174 message_set_envelope (msg, envelope, mum);
1175 }
1163 1176
1164 /* Attach the message to the mailbox mbox data. */ 1177 /* Attach the message to the mailbox mbox data. */
1165 mum->message = msg; 1178 mum->message = msg;
...@@ -1229,7 +1242,9 @@ mbox_append_message (mailbox_t mailbox, message_t msg) ...@@ -1229,7 +1242,9 @@ mbox_append_message (mailbox_t mailbox, message_t msg)
1229 { 1242 {
1230 char *s; 1243 char *s;
1231 size_t len = 0; 1244 size_t len = 0;
1232 status = message_from (msg, mud->from, 127, &len); 1245 envelope_t envelope;
1246 message_get_envelope (msg, &envelope);
1247 status = envelope_from (envelope, mud->from, 127, &len);
1233 if (status != 0) 1248 if (status != 0)
1234 { 1249 {
1235 if (status != EAGAIN) 1250 if (status != EAGAIN)
...@@ -1255,7 +1270,9 @@ mbox_append_message (mailbox_t mailbox, message_t msg) ...@@ -1255,7 +1270,9 @@ mbox_append_message (mailbox_t mailbox, message_t msg)
1255 { 1270 {
1256 char *s; 1271 char *s;
1257 size_t len = 0; 1272 size_t len = 0;
1258 status = message_received (msg, mud->date, 127, &len); 1273 envelope_t envelope;
1274 message_get_envelope (msg, &envelope);
1275 status = envelope_date (envelope, mud->date, 127, &len);
1259 if (status != 0) 1276 if (status != 0)
1260 { 1277 {
1261 if (status != EAGAIN) 1278 if (status != EAGAIN)
......
...@@ -352,7 +352,7 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) ...@@ -352,7 +352,7 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif)
352 mum->mud = mud; 352 mum->mud = mud;
353 mum->header_from = total - n; 353 mum->header_from = total - n;
354 mum->header_from_end = total; 354 mum->header_from_end = total;
355 mum->body_end = 0; 355 mum->body_end = mum->body = 0;
356 lines = 0; 356 lines = 0;
357 } 357 }
358 else if ((n > 7) && ISSTATUS(buf)) 358 else if ((n > 7) && ISSTATUS(buf))
......
...@@ -196,7 +196,7 @@ do \ ...@@ -196,7 +196,7 @@ do \
196 || (mpd->id && mpd->id != (size_t)identity)) \ 196 || (mpd->id && mpd->id != (size_t)identity)) \
197 { \ 197 { \
198 mpd->id = 0; \ 198 mpd->id = 0; \
199 mpd->func = pop_open; \ 199 mpd->func = (void *)pop_open; \
200 mpd->state = POP_NO_STATE; \ 200 mpd->state = POP_NO_STATE; \
201 monitor_unlock (mbox->monitor); \ 201 monitor_unlock (mbox->monitor); \
202 err = pop_open (mbox, mbox->flags); \ 202 err = pop_open (mbox, mbox->flags); \
......
...@@ -37,18 +37,29 @@ static int message_read (stream_t is, char *buf, size_t buflen, ...@@ -37,18 +37,29 @@ static int message_read (stream_t is, char *buf, size_t buflen,
37 static int message_write (stream_t os, const char *buf, size_t buflen, 37 static int message_write (stream_t os, const char *buf, size_t buflen,
38 off_t off, size_t *pnwrite); 38 off_t off, size_t *pnwrite);
39 static int message_get_fd (stream_t stream, int *pfd); 39 static int message_get_fd (stream_t stream, int *pfd);
40 static int message_from (envelope_t envelope, char *buf, size_t len,
41 size_t *pnwrite);
42 static int message_date (envelope_t envelope, char *buf, size_t len,
43 size_t *pnwrite);
40 44
41 /* Allocate ressources for the message_t. */ 45 /* Allocate ressources for the message_t. */
42 int 46 int
43 message_create (message_t *pmsg, void *owner) 47 message_create (message_t *pmsg, void *owner)
44 { 48 {
45 message_t msg; 49 message_t msg;
50 int status;
46 51
47 if (pmsg == NULL) 52 if (pmsg == NULL)
48 return EINVAL; 53 return EINVAL;
49 msg = calloc (1, sizeof (*msg)); 54 msg = calloc (1, sizeof (*msg));
50 if (msg == NULL) 55 if (msg == NULL)
51 return ENOMEM; 56 return ENOMEM;
57 status = monitor_create (&(msg->monitor), msg);
58 if (status != 0)
59 {
60 free (msg);
61 return status;
62 }
52 msg->owner = owner; 63 msg->owner = owner;
53 msg->ref = 1; 64 msg->ref = 1;
54 *pmsg = msg; 65 *pmsg = msg;
...@@ -61,11 +72,15 @@ message_destroy (message_t *pmsg, void *owner) ...@@ -61,11 +72,15 @@ message_destroy (message_t *pmsg, void *owner)
61 if (pmsg && *pmsg) 72 if (pmsg && *pmsg)
62 { 73 {
63 message_t msg = *pmsg; 74 message_t msg = *pmsg;
75 monitor_t monitor = msg->monitor;
76 int destroy_lock = 0;
64 77
78 monitor_wrlock (monitor);
65 msg->ref--; 79 msg->ref--;
66 if ((msg->owner && msg->owner == owner) 80 if ((msg->owner && msg->owner == owner)
67 || (msg->owner == NULL && msg->ref <= 0)) 81 || (msg->owner == NULL && msg->ref <= 0))
68 { 82 {
83 destroy_lock = 1;
69 /* Notify the listeners. */ 84 /* Notify the listeners. */
70 /* FIXME: to be removed since we do not supoort this event. */ 85 /* FIXME: to be removed since we do not supoort this event. */
71 if (msg->observable) 86 if (msg->observable)
...@@ -74,10 +89,18 @@ message_destroy (message_t *pmsg, void *owner) ...@@ -74,10 +89,18 @@ message_destroy (message_t *pmsg, void *owner)
74 observable_destroy (&(msg->observable), msg); 89 observable_destroy (&(msg->observable), msg);
75 } 90 }
76 91
92 /* Envelope. */
93 if (msg->envelope)
94 envelope_destroy (&(msg->envelope), msg);
95
77 /* Header. */ 96 /* Header. */
78 if (msg->header) 97 if (msg->header)
79 header_destroy (&(msg->header), msg); 98 header_destroy (&(msg->header), msg);
80 99
100 /* Body. */
101 if (msg->body)
102 body_destroy (&(msg->body), msg);
103
81 /* Attribute. */ 104 /* Attribute. */
82 if (msg->attribute) 105 if (msg->attribute)
83 attribute_destroy (&(msg->attribute), msg); 106 attribute_destroy (&(msg->attribute), msg);
...@@ -86,10 +109,6 @@ message_destroy (message_t *pmsg, void *owner) ...@@ -86,10 +109,6 @@ message_destroy (message_t *pmsg, void *owner)
86 if (msg->stream) 109 if (msg->stream)
87 stream_destroy (&(msg->stream), msg); 110 stream_destroy (&(msg->stream), msg);
88 111
89 /* Body. */
90 if (msg->body)
91 body_destroy (&(msg->body), msg);
92
93 /* Mime. */ 112 /* Mime. */
94 if (msg->mime) 113 if (msg->mime)
95 mime_destroy (&(msg->mime)); 114 mime_destroy (&(msg->mime));
...@@ -100,6 +119,9 @@ message_destroy (message_t *pmsg, void *owner) ...@@ -100,6 +119,9 @@ message_destroy (message_t *pmsg, void *owner)
100 if (msg->ref <= 0) 119 if (msg->ref <= 0)
101 free (msg); 120 free (msg);
102 } 121 }
122 monitor_unlock (monitor);
123 if (destroy_lock)
124 monitor_destroy (&monitor, msg);
103 /* Loose the link */ 125 /* Loose the link */
104 *pmsg = NULL; 126 *pmsg = NULL;
105 } 127 }
...@@ -109,7 +131,11 @@ int ...@@ -109,7 +131,11 @@ int
109 message_ref (message_t msg) 131 message_ref (message_t msg)
110 { 132 {
111 if (msg) 133 if (msg)
134 {
135 monitor_wrlock (msg->monitor);
112 msg->ref++; 136 msg->ref++;
137 monitor_unlock (msg->monitor);
138 }
113 return 0; 139 return 0;
114 } 140 }
115 141
...@@ -126,14 +152,19 @@ message_get_header (message_t msg, header_t *phdr) ...@@ -126,14 +152,19 @@ message_get_header (message_t msg, header_t *phdr)
126 return EINVAL; 152 return EINVAL;
127 153
128 /* Is it a floating mesg */ 154 /* Is it a floating mesg */
155 monitor_wrlock (msg->monitor);
129 if (msg->header == NULL) 156 if (msg->header == NULL)
130 { 157 {
131 header_t header; 158 header_t header;
132 int status = header_create (&header, NULL, 0, msg); 159 int status = header_create (&header, NULL, 0, msg);
133 if (status != 0) 160 if (status != 0)
161 {
162 monitor_unlock (msg->monitor);
134 return status; 163 return status;
164 }
135 msg->header = header; 165 msg->header = header;
136 } 166 }
167 monitor_unlock (msg->monitor);
137 *phdr = msg->header; 168 *phdr = msg->header;
138 return 0; 169 return 0;
139 } 170 }
...@@ -147,8 +178,11 @@ message_set_header (message_t msg, header_t hdr, void *owner) ...@@ -147,8 +178,11 @@ message_set_header (message_t msg, header_t hdr, void *owner)
147 return EACCES; 178 return EACCES;
148 /* Make sure we destoy the old if it was own by the mesg */ 179 /* Make sure we destoy the old if it was own by the mesg */
149 /* FIXME: I do not know if somebody has already a ref on this ? */ 180 /* FIXME: I do not know if somebody has already a ref on this ? */
181 monitor_wrlock (msg->monitor);
182 if (msg->header)
150 header_destroy (&(msg->header), msg); 183 header_destroy (&(msg->header), msg);
151 msg->header = hdr; 184 msg->header = hdr;
185 monitor_unlock (msg->monitor);
152 return 0; 186 return 0;
153 } 187 }
154 188
...@@ -158,15 +192,20 @@ message_get_body (message_t msg, body_t *pbody) ...@@ -158,15 +192,20 @@ message_get_body (message_t msg, body_t *pbody)
158 if (msg == NULL || pbody == NULL) 192 if (msg == NULL || pbody == NULL)
159 return EINVAL; 193 return EINVAL;
160 194
195 monitor_wrlock (msg->monitor);
161 /* Is it a floating mesg. */ 196 /* Is it a floating mesg. */
162 if (msg->body == NULL) 197 if (msg->body == NULL)
163 { 198 {
164 body_t body; 199 body_t body;
165 int status = body_create (&body, msg); 200 int status = body_create (&body, msg);
166 if (status != 0) 201 if (status != 0)
202 {
203 monitor_unlock (msg->monitor);
167 return status; 204 return status;
205 }
168 msg->body = body; 206 msg->body = body;
169 } 207 }
208 monitor_unlock (msg->monitor);
170 *pbody = msg->body; 209 *pbody = msg->body;
171 return 0; 210 return 0;
172 } 211 }
...@@ -180,8 +219,11 @@ message_set_body (message_t msg, body_t body, void *owner) ...@@ -180,8 +219,11 @@ message_set_body (message_t msg, body_t body, void *owner)
180 return EACCES; 219 return EACCES;
181 /* Make sure we destoy the old if it was own by the mesg. */ 220 /* Make sure we destoy the old if it was own by the mesg. */
182 /* FIXME: I do not know if somebody has already a ref on this ? */ 221 /* FIXME: I do not know if somebody has already a ref on this ? */
222 monitor_wrlock (msg->monitor);
223 if (msg->body)
183 body_destroy (&(msg->body), msg); 224 body_destroy (&(msg->body), msg);
184 msg->body = body; 225 msg->body = body;
226 monitor_unlock (msg->monitor);
185 return 0; 227 return 0;
186 } 228 }
187 229
...@@ -194,8 +236,11 @@ message_set_stream (message_t msg, stream_t stream, void *owner) ...@@ -194,8 +236,11 @@ message_set_stream (message_t msg, stream_t stream, void *owner)
194 return EACCES; 236 return EACCES;
195 /* Make sure we destoy the old if it was own by the mesg. */ 237 /* Make sure we destoy the old if it was own by the mesg. */
196 /* FIXME: I do not know if somebody has already a ref on this ? */ 238 /* FIXME: I do not know if somebody has already a ref on this ? */
239 monitor_wrlock (msg->monitor);
240 if (msg->stream)
197 stream_destroy (&(msg->stream), msg); 241 stream_destroy (&(msg->stream), msg);
198 msg->stream = stream; 242 msg->stream = stream;
243 monitor_unlock (msg->monitor);
199 return 0; 244 return 0;
200 } 245 }
201 246
...@@ -205,19 +250,24 @@ message_get_stream (message_t msg, stream_t *pstream) ...@@ -205,19 +250,24 @@ message_get_stream (message_t msg, stream_t *pstream)
205 if (msg == NULL || pstream == NULL) 250 if (msg == NULL || pstream == NULL)
206 return EINVAL; 251 return EINVAL;
207 252
253 monitor_wrlock (msg->monitor);
208 if (msg->stream == NULL) 254 if (msg->stream == NULL)
209 { 255 {
210 stream_t stream; 256 stream_t stream;
211 int status; 257 int status;
212 status = stream_create (&stream, MU_STREAM_RDWR, msg); 258 status = stream_create (&stream, MU_STREAM_RDWR, msg);
213 if (status != 0) 259 if (status != 0)
260 {
261 monitor_unlock (msg->monitor);
214 return status; 262 return status;
263 }
215 stream_set_read (stream, message_read, msg); 264 stream_set_read (stream, message_read, msg);
216 stream_set_write (stream, message_write, msg); 265 stream_set_write (stream, message_write, msg);
217 stream_set_fd (stream, message_get_fd, msg); 266 stream_set_fd (stream, message_get_fd, msg);
218 stream_set_flags (stream, MU_STREAM_RDWR); 267 stream_set_flags (stream, MU_STREAM_RDWR);
219 msg->stream = stream; 268 msg->stream = stream;
220 } 269 }
270 monitor_unlock (msg->monitor);
221 271
222 *pstream = msg->stream; 272 *pstream = msg->stream;
223 return 0; 273 return 0;
...@@ -290,123 +340,42 @@ message_size (message_t msg, size_t *psize) ...@@ -290,123 +340,42 @@ message_size (message_t msg, size_t *psize)
290 } 340 }
291 341
292 int 342 int
293 message_set_from (message_t msg, 343 message_get_envelope (message_t msg, envelope_t *penvelope)
294 int (*_from) __P ((message_t, char *, size_t, size_t*)),
295 void *owner)
296 {
297 if (msg == NULL)
298 return EINVAL;
299 if (msg->owner != owner)
300 return EACCES;
301 msg->_from = _from;
302 return 0;
303 }
304
305 int
306 message_from (message_t msg, char *buf, size_t len, size_t *pnwrite)
307 { 344 {
308 header_t header = NULL; 345 if (msg == NULL || penvelope == NULL)
309 size_t n = 0;
310 int status;
311
312 if (msg == NULL)
313 return EINVAL; 346 return EINVAL;
314 347
315 /* Did they provide a way to get it ? */ 348 monitor_wrlock (msg->monitor);
316 if (msg->_from) 349 if (msg->envelope == NULL)
317 return msg->_from (msg, buf, len, pnwrite);
318
319 /* Can it be extracted from the From: */
320 message_get_header (msg, &header);
321 status = header_get_value (header, MU_HEADER_FROM, NULL, 0, &n);
322 if (status == 0 && n != 0)
323 {
324 char *from;
325 char *addr;
326 from = calloc (1, n + 1);
327 if (from == NULL)
328 return ENOMEM;
329 addr = calloc (1, n + 1);
330 if (addr == NULL)
331 { 350 {
332 free (from); 351 envelope_t envelope;
333 return ENOMEM; 352 int status = envelope_create (&envelope, msg);
334 } 353 if (status != 0)
335 header_get_value (header, MU_HEADER_FROM, from, n + 1, NULL);
336 if (parseaddr (from, addr, n + 1) == 0)
337 {
338 size_t i = strlen (addr);
339 n = (i > len) ? len : i;
340 if (buf && len > 0)
341 { 354 {
342 memcpy (buf, addr, n); 355 monitor_unlock (msg->monitor);
343 buf[n] = '\0';
344 }
345 free (addr);
346 free (from);
347 if (pnwrite)
348 *pnwrite = n;
349 return 0;
350 }
351 }
352 else if (status == EAGAIN)
353 return status; 356 return status;
354
355 /* oops */
356 n = (7 > len) ? len: 7;
357 if (buf && len > 0)
358 {
359 memcpy (buf, "unknown", n);
360 buf [n] = '\0';
361 } 357 }
362 358 envelope_set_from (envelope, message_from, msg);
363 if (pnwrite) 359 envelope_set_date (envelope, message_date, msg);
364 *pnwrite = n; 360 msg->envelope = envelope;
361 }
362 monitor_unlock (msg->monitor);
363 *penvelope = msg->envelope;
365 return 0; 364 return 0;
366 } 365 }
367 366
368 int 367 int
369 message_set_received (message_t msg, int (*_received) 368 message_set_envelope (message_t msg, envelope_t envelope, void *owner)
370 __P ((message_t, char *, size_t , size_t *)),
371 void *owner)
372 { 369 {
373 if (msg == NULL) 370 if (msg == NULL)
374 return EINVAL; 371 return EINVAL;
375 if (msg->owner != owner) 372 if (msg->owner != owner)
376 return EACCES; 373 return EACCES;
377 msg->_received = _received; 374 monitor_wrlock (msg->monitor);
378 return 0; 375 if (msg->envelope)
379 } 376 envelope_destroy (&(msg->envelope), msg);
380 377 msg->envelope = envelope;
381 int 378 monitor_unlock (msg->monitor);
382 message_received (message_t msg, char *buf, size_t len, size_t *pnwrite)
383 {
384 time_t t;
385 size_t n;
386 if (msg == NULL)
387 return EINVAL;
388 /* Is it provided ? */
389 if (msg->_received)
390 return msg->_received (msg, buf, len, pnwrite);
391
392 /* FIXME: extract the time from "Date:". */
393
394 /* Catch all. */
395 /* FIXME: ctime() is not thread safe use strftime(). */
396 t = time (NULL);
397 n = strlen (ctime (&t));
398
399 if (buf == NULL || len == 0)
400 {
401 if (pnwrite)
402 *pnwrite = n;
403 return 0;
404 }
405 n = (n > len) ? len : n;
406 strncpy (buf, ctime (&t), n);
407 buf [n] = '\0';
408 if (pnwrite)
409 *pnwrite = n;
410 return 0; 379 return 0;
411 } 380 }
412 381
...@@ -415,14 +384,19 @@ message_get_attribute (message_t msg, attribute_t *pattribute) ...@@ -415,14 +384,19 @@ message_get_attribute (message_t msg, attribute_t *pattribute)
415 { 384 {
416 if (msg == NULL || pattribute == NULL) 385 if (msg == NULL || pattribute == NULL)
417 return EINVAL; 386 return EINVAL;
387 monitor_wrlock (msg->monitor);
418 if (msg->attribute == NULL) 388 if (msg->attribute == NULL)
419 { 389 {
420 attribute_t attribute; 390 attribute_t attribute;
421 int status = attribute_create (&attribute, msg); 391 int status = attribute_create (&attribute, msg);
422 if (status != 0) 392 if (status != 0)
393 {
394 monitor_unlock (msg->monitor);
423 return status; 395 return status;
396 }
424 msg->attribute = attribute; 397 msg->attribute = attribute;
425 } 398 }
399 monitor_unlock (msg->monitor);
426 *pattribute = msg->attribute; 400 *pattribute = msg->attribute;
427 return 0; 401 return 0;
428 } 402 }
...@@ -434,8 +408,11 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner) ...@@ -434,8 +408,11 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner)
434 return EINVAL; 408 return EINVAL;
435 if (msg->owner != owner) 409 if (msg->owner != owner)
436 return EACCES; 410 return EACCES;
411 monitor_wrlock (msg->monitor);
412 if (msg->attribute)
437 attribute_destroy (&(msg->attribute), owner); 413 attribute_destroy (&(msg->attribute), owner);
438 msg->attribute = attribute; 414 msg->attribute = attribute;
415 monitor_unlock (msg->monitor);
439 return 0; 416 return 0;
440 } 417 }
441 418
...@@ -540,12 +517,17 @@ message_get_num_parts (message_t msg, size_t *pparts) ...@@ -540,12 +517,17 @@ message_get_num_parts (message_t msg, size_t *pparts)
540 if (msg->_get_num_parts) 517 if (msg->_get_num_parts)
541 return msg->_get_num_parts (msg, pparts); 518 return msg->_get_num_parts (msg, pparts);
542 519
520 monitor_wrlock (msg->monitor);
543 if (msg->mime == NULL) 521 if (msg->mime == NULL)
544 { 522 {
545 int status = mime_create (&(msg->mime), msg, 0); 523 int status = mime_create (&(msg->mime), msg, 0);
546 if (status != 0) 524 if (status != 0)
525 {
526 monitor_unlock (msg->monitor);
547 return status; 527 return status;
548 } 528 }
529 }
530 monitor_unlock (msg->monitor);
549 return mime_get_num_parts (msg->mime, pparts); 531 return mime_get_num_parts (msg->mime, pparts);
550 } 532 }
551 533
...@@ -571,12 +553,17 @@ message_get_part (message_t msg, size_t part, message_t *pmsg) ...@@ -571,12 +553,17 @@ message_get_part (message_t msg, size_t part, message_t *pmsg)
571 if (msg->_get_part) 553 if (msg->_get_part)
572 return msg->_get_part (msg, part, pmsg); 554 return msg->_get_part (msg, part, pmsg);
573 555
556 monitor_wrlock (msg->monitor);
574 if (msg->mime == NULL) 557 if (msg->mime == NULL)
575 { 558 {
576 int status = mime_create (&(msg->mime), msg, 0); 559 int status = mime_create (&(msg->mime), msg, 0);
577 if (status != 0) 560 if (status != 0)
561 {
562 monitor_unlock (msg->monitor);
578 return status; 563 return status;
579 } 564 }
565 }
566 monitor_unlock (msg->monitor);
580 return mime_get_part (msg->mime, part, pmsg); 567 return mime_get_part (msg->mime, part, pmsg);
581 } 568 }
582 569
...@@ -599,12 +586,17 @@ message_get_observable (message_t msg, observable_t *pobservable) ...@@ -599,12 +586,17 @@ message_get_observable (message_t msg, observable_t *pobservable)
599 if (msg == NULL || pobservable == NULL) 586 if (msg == NULL || pobservable == NULL)
600 return EINVAL; 587 return EINVAL;
601 588
589 monitor_wrlock (msg->monitor);
602 if (msg->observable == NULL) 590 if (msg->observable == NULL)
603 { 591 {
604 int status = observable_create (&(msg->observable), msg); 592 int status = observable_create (&(msg->observable), msg);
605 if (status != 0) 593 if (status != 0)
594 {
595 monitor_unlock (msg->monitor);
606 return status; 596 return status;
607 } 597 }
598 }
599 monitor_unlock (msg->monitor);
608 *pobservable = msg->observable; 600 *pobservable = msg->observable;
609 return 0; 601 return 0;
610 } 602 }
...@@ -665,6 +657,7 @@ message_write (stream_t os, const char *buf, size_t buflen, ...@@ -665,6 +657,7 @@ message_write (stream_t os, const char *buf, size_t buflen,
665 return 0; 657 return 0;
666 } 658 }
667 659
660 monitor_wrlock (msg->monitor);
668 if (!msg->hdr_done) 661 if (!msg->hdr_done)
669 { 662 {
670 size_t len; 663 size_t len;
...@@ -680,6 +673,7 @@ message_write (stream_t os, const char *buf, size_t buflen, ...@@ -680,6 +673,7 @@ message_write (stream_t os, const char *buf, size_t buflen,
680 free (msg->hdr_buf); 673 free (msg->hdr_buf);
681 msg->hdr_buf = NULL; 674 msg->hdr_buf = NULL;
682 msg->hdr_buflen = 0; 675 msg->hdr_buflen = 0;
676 monitor_unlock (msg->monitor);
683 return ENOMEM; 677 return ENOMEM;
684 } 678 }
685 else 679 else
...@@ -698,6 +692,7 @@ message_write (stream_t os, const char *buf, size_t buflen, ...@@ -698,6 +692,7 @@ message_write (stream_t os, const char *buf, size_t buflen,
698 if (status != 0) 692 if (status != 0)
699 { 693 {
700 msg->hdr_buflen = 0; 694 msg->hdr_buflen = 0;
695 monitor_unlock (msg->monitor);
701 return status; 696 return status;
702 } 697 }
703 msg->hdr_done = 1; 698 msg->hdr_done = 1;
...@@ -706,16 +701,19 @@ message_write (stream_t os, const char *buf, size_t buflen, ...@@ -706,16 +701,19 @@ message_write (stream_t os, const char *buf, size_t buflen,
706 buflen -= len; 701 buflen -= len;
707 } 702 }
708 } 703 }
704 monitor_unlock (msg->monitor);
709 705
710 /* Message header is not complete but was not a full line. */ 706 /* Message header is not complete but was not a full line. */
711 if (!msg->hdr_done && buflen > 0) 707 if (!msg->hdr_done && buflen > 0)
712 { 708 {
713 char *thdr = realloc (msg->hdr_buf, msg->hdr_buflen + buflen); 709 char *thdr = realloc (msg->hdr_buf, msg->hdr_buflen + buflen);
710 monitor_wrlock (msg->monitor);
714 if (thdr == NULL) 711 if (thdr == NULL)
715 { 712 {
716 free (msg->hdr_buf); 713 free (msg->hdr_buf);
717 msg->hdr_buf = NULL; 714 msg->hdr_buf = NULL;
718 msg->hdr_buflen = 0; 715 msg->hdr_buflen = 0;
716 monitor_unlock (msg->monitor);
719 return ENOMEM; 717 return ENOMEM;
720 } 718 }
721 else 719 else
...@@ -723,6 +721,7 @@ message_write (stream_t os, const char *buf, size_t buflen, ...@@ -723,6 +721,7 @@ message_write (stream_t os, const char *buf, size_t buflen,
723 memcpy (msg->hdr_buf + msg->hdr_buflen, buf, buflen); 721 memcpy (msg->hdr_buf + msg->hdr_buflen, buf, buflen);
724 msg->hdr_buflen += buflen; 722 msg->hdr_buflen += buflen;
725 buflen = 0; 723 buflen = 0;
724 monitor_unlock (msg->monitor);
726 } 725 }
727 else if (buflen > 0) /* In the body. */ 726 else if (buflen > 0) /* In the body. */
728 { 727 {
...@@ -759,18 +758,115 @@ message_get_fd (stream_t stream, int *pfd) ...@@ -759,18 +758,115 @@ message_get_fd (stream_t stream, int *pfd)
759 if (msg == NULL) 758 if (msg == NULL)
760 return EINVAL; 759 return EINVAL;
761 760
761 monitor_wrlock (msg->monitor);
762 /* Probably being lazy, then create a body for the stream. */ 762 /* Probably being lazy, then create a body for the stream. */
763 if (msg->body == NULL) 763 if (msg->body == NULL)
764 { 764 {
765 int status = body_create (&body, msg); 765 int status = body_create (&body, msg);
766 if (status != 0 ) 766 if (status != 0 )
767 767 {
768 monitor_unlock (msg->monitor);
768 return status; 769 return status;
770 }
769 msg->body = body; 771 msg->body = body;
770 } 772 }
771 else 773 else
772 body = msg->body; 774 body = msg->body;
775 monitor_unlock (msg->monitor);
773 776
774 body_get_stream (body, &is); 777 body_get_stream (body, &is);
775 return stream_get_fd (is, pfd); 778 return stream_get_fd (is, pfd);
776 } 779 }
780
781 static int
782 message_date (envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
783 {
784 message_t msg = envelope_get_owner (envelope);
785 time_t t;
786 size_t n;
787
788 if (msg == NULL)
789 return EINVAL;
790
791 /* FIXME: extract the time from "Date:". */
792
793 /* Catch all. */
794 /* FIXME: ctime() is not thread safe use strftime(). */
795 t = time (NULL);
796 n = strlen (ctime (&t));
797
798 if (buf == NULL || len == 0)
799 {
800 if (pnwrite)
801 *pnwrite = n;
802 return 0;
803 }
804 n = (n > len) ? len : n;
805 strncpy (buf, ctime (&t), n);
806 buf [n] = '\0';
807 if (pnwrite)
808 *pnwrite = n;
809 return 0;
810 }
811
812 static int
813 message_from (envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
814 {
815 message_t msg = envelope_get_owner (envelope);
816 header_t header = NULL;
817 size_t n = 0;
818 int status;
819
820 if (msg == NULL)
821 return EINVAL;
822
823 /* Can it be extracted from the From: */
824 message_get_header (msg, &header);
825 status = header_get_value (header, MU_HEADER_FROM, NULL, 0, &n);
826 if (status == 0 && n != 0)
827 {
828 char *from;
829 char *addr;
830 from = calloc (1, n + 1);
831 if (from == NULL)
832 return ENOMEM;
833 addr = calloc (1, n + 1);
834 if (addr == NULL)
835 {
836 free (from);
837 return ENOMEM;
838 }
839 header_get_value (header, MU_HEADER_FROM, from, n + 1, NULL);
840 if (parseaddr (from, addr, n + 1) == 0)
841 {
842 size_t i = strlen (addr);
843 n = (i > len) ? len : i;
844 if (buf && len > 0)
845 {
846 memcpy (buf, addr, n);
847 buf[n] = '\0';
848 }
849 free (addr);
850 free (from);
851 if (pnwrite)
852 *pnwrite = n;
853 return 0;
854 }
855 free (addr);
856 free (from);
857 }
858 else if (status == EAGAIN)
859 return status;
860
861 /* oops */
862 n = (7 > len) ? len: 7;
863 if (buf && len > 0)
864 {
865 memcpy (buf, "unknown", n);
866 buf [n] = '\0';
867 }
868
869 if (pnwrite)
870 *pnwrite = n;
871 return 0;
872 }
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
21 #include <stdlib.h> 21 #include <stdlib.h>
22 #include <string.h> 22 #include <string.h>
23 #include <ctype.h> 23 #include <ctype.h>
24 #include <unistd.h>
25 #include <time.h> 24 #include <time.h>
25 #include <unistd.h>
26 26
27 #include <mailutils/message.h> 27 #include <mailutils/message.h>
28 #include <mailutils/stream.h> 28 #include <mailutils/stream.h>
...@@ -217,7 +217,7 @@ static void _mime_append_header_line(mime_t mime) ...@@ -217,7 +217,7 @@ static void _mime_append_header_line(mime_t mime)
217 static int _mime_parse_mpart_message(mime_t mime) 217 static int _mime_parse_mpart_message(mime_t mime)
218 { 218 {
219 char *cp, *cp2; 219 char *cp, *cp2;
220 int blength, body_length, body_offset, body_lines, ret; 220 int blength, mb_length, mb_offset, mb_lines, ret;
221 size_t nbytes; 221 size_t nbytes;
222 222
223 if ( !(mime->flags & MIME_PARSER_ACTIVE) ) { 223 if ( !(mime->flags & MIME_PARSER_ACTIVE) ) {
...@@ -237,9 +237,9 @@ static int _mime_parse_mpart_message(mime_t mime) ...@@ -237,9 +237,9 @@ static int _mime_parse_mpart_message(mime_t mime)
237 mime->parser_state = MIME_STATE_SCAN_BOUNDARY; 237 mime->parser_state = MIME_STATE_SCAN_BOUNDARY;
238 mime->flags |= MIME_PARSER_ACTIVE; 238 mime->flags |= MIME_PARSER_ACTIVE;
239 } 239 }
240 body_length = mime->body_length; 240 mb_length = mime->body_length;
241 body_offset = mime->body_offset; 241 mb_offset = mime->body_offset;
242 body_lines = mime->body_lines; 242 mb_lines = mime->body_lines;
243 243
244 while ( ( ret = stream_read(mime->stream, mime->cur_buf, mime->buf_size, mime->cur_offset, &nbytes) ) == 0 && nbytes ) { 244 while ( ( ret = stream_read(mime->stream, mime->cur_buf, mime->buf_size, mime->cur_offset, &nbytes) ) == 0 && nbytes ) {
245 cp = mime->cur_buf; 245 cp = mime->cur_buf;
...@@ -256,15 +256,15 @@ static int _mime_parse_mpart_message(mime_t mime) ...@@ -256,15 +256,15 @@ static int _mime_parse_mpart_message(mime_t mime)
256 cp2 = mime->cur_line[0] == '\n' ? mime->cur_line + 1 : mime->cur_line; 256 cp2 = mime->cur_line[0] == '\n' ? mime->cur_line + 1 : mime->cur_line;
257 blength = strlen(mime->boundary); 257 blength = strlen(mime->boundary);
258 if ( mime->header_length ) 258 if ( mime->header_length )
259 body_lines++; 259 mb_lines++;
260 if ( mime->line_ndx >= blength ) { 260 if ( mime->line_ndx >= blength ) {
261 if ( ( !strncasecmp(cp2,"--", 2) && !strncasecmp(cp2+2, mime->boundary, blength) ) 261 if ( ( !strncasecmp(cp2,"--", 2) && !strncasecmp(cp2+2, mime->boundary, blength) )
262 || !strncasecmp(cp2, mime->boundary, blength) ) { 262 || !strncasecmp(cp2, mime->boundary, blength) ) {
263 mime->parser_state = MIME_STATE_HEADERS; 263 mime->parser_state = MIME_STATE_HEADERS;
264 mime->flags &= ~MIME_PARSER_HAVE_CR; 264 mime->flags &= ~MIME_PARSER_HAVE_CR;
265 body_length = mime->cur_offset - body_offset - mime->line_ndx + 1; 265 mb_length = mime->cur_offset - mb_offset - mime->line_ndx + 1;
266 if ( mime->header_length ) /* this skips the preamble */ 266 if ( mime->header_length ) /* this skips the preamble */
267 _mime_append_part(mime, NULL, body_offset, body_length, body_lines); 267 _mime_append_part(mime, NULL, mb_offset, mb_length, mb_lines);
268 if ( ( cp2 + blength + 2 < cp && !strncasecmp(cp2+2+blength, "--",2) ) || 268 if ( ( cp2 + blength + 2 < cp && !strncasecmp(cp2+2+blength, "--",2) ) ||
269 !strncasecmp(cp2+blength, "--",2) ) { /* very last boundary */ 269 !strncasecmp(cp2+blength, "--",2) ) { /* very last boundary */
270 mime->parser_state = MIME_STATE_BEGIN_LINE; 270 mime->parser_state = MIME_STATE_BEGIN_LINE;
...@@ -283,8 +283,8 @@ static int _mime_parse_mpart_message(mime_t mime) ...@@ -283,8 +283,8 @@ static int _mime_parse_mpart_message(mime_t mime)
283 _mime_append_header_line(mime); 283 _mime_append_header_line(mime);
284 if ( mime->line_ndx == 1 || mime->cur_line[0] == '\r' ) { 284 if ( mime->line_ndx == 1 || mime->cur_line[0] == '\r' ) {
285 mime->parser_state = MIME_STATE_BEGIN_LINE; 285 mime->parser_state = MIME_STATE_BEGIN_LINE;
286 body_offset = mime->cur_offset + 1; 286 mb_offset = mime->cur_offset + 1;
287 body_lines = 0; 287 mb_lines = 0;
288 } 288 }
289 mime->line_ndx = -1; 289 mime->line_ndx = -1;
290 break; 290 break;
...@@ -300,12 +300,12 @@ static int _mime_parse_mpart_message(mime_t mime) ...@@ -300,12 +300,12 @@ static int _mime_parse_mpart_message(mime_t mime)
300 cp++; 300 cp++;
301 } 301 }
302 } 302 }
303 mime->body_lines = body_lines; 303 mime->body_lines = mb_lines;
304 mime->body_length = body_length; 304 mime->body_length = mb_length;
305 mime->body_offset = body_offset; 305 mime->body_offset = mb_offset;
306 if ( ret != EAGAIN ) { /* finished cleanup */ 306 if ( ret != EAGAIN ) { /* finished cleanup */
307 if ( mime->header_length ) /* this skips the preamble */ 307 if ( mime->header_length ) /* this skips the preamble */
308 _mime_append_part(mime, NULL, body_offset, body_length, body_lines); 308 _mime_append_part(mime, NULL, mb_offset, mb_length, mb_lines);
309 mime->flags &= ~MIME_PARSER_ACTIVE; 309 mime->flags &= ~MIME_PARSER_ACTIVE;
310 mime->body_offset = mime->body_length = mime->header_length = mime->body_lines = 0; 310 mime->body_offset = mime->body_length = mime->header_length = mime->body_lines = 0;
311 } 311 }
...@@ -382,7 +382,7 @@ static int _mime_set_content_type(mime_t mime) ...@@ -382,7 +382,7 @@ static int _mime_set_content_type(mime_t mime)
382 else 382 else
383 strcpy(content_type, "multipart/alternative; boundary="); 383 strcpy(content_type, "multipart/alternative; boundary=");
384 if ( mime->boundary == NULL ) { 384 if ( mime->boundary == NULL ) {
385 sprintf (boundary,"%ld-%ld=:%ld",random (),time (0), getpid ()); 385 sprintf (boundary,"%ld-%ld=:%ld",(long)random (), (long)time (0), (long)getpid ());
386 if ( ( mime->boundary = strdup(boundary) ) == NULL ) 386 if ( ( mime->boundary = strdup(boundary) ) == NULL )
387 return ENOMEM; 387 return ENOMEM;
388 } 388 }
...@@ -465,9 +465,12 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, ...@@ -465,9 +465,12 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off,
465 return 0; 465 return 0;
466 message_get_stream(mime->mtp_parts[mime->cur_part]->msg, &msg_stream); 466 message_get_stream(mime->mtp_parts[mime->cur_part]->msg, &msg_stream);
467 } else { 467 } else {
468 body_t b; 468 body_t part_body;
469 message_get_body(mime->mtp_parts[mime->cur_part]->msg, &b); 469
470 body_get_stream(b, &msg_stream); 470 if ( mime->cur_part >= mime->nmtp_parts )
471 return 0;
472 message_get_body(mime->mtp_parts[mime->cur_part]->msg, &part_body);
473 body_get_stream(part_body, &msg_stream);
471 } 474 }
472 ret = stream_read(msg_stream, buf, buflen, mime->part_offset, &part_nbytes ); 475 ret = stream_read(msg_stream, buf, buflen, mime->part_offset, &part_nbytes );
473 len += part_nbytes; 476 len += part_nbytes;
...@@ -475,11 +478,11 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, ...@@ -475,11 +478,11 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off,
475 if ( nbytes ) 478 if ( nbytes )
476 *nbytes += len; 479 *nbytes += len;
477 mime->cur_offset += len; 480 mime->cur_offset += len;
478 if ( ret == 0 && part_nbytes == 0 && mime->nmtp_parts > 1 ) { 481 if ( ret == 0 && part_nbytes == 0 ) {
479 mime->flags |= MIME_INSERT_BOUNDARY; 482 mime->flags |= MIME_INSERT_BOUNDARY;
480 mime->cur_part++; 483 mime->cur_part++;
481 } 484 }
482 } while( ret == 0 && part_nbytes == 0 && mime->cur_part < mime->nmtp_parts ); 485 } while( ret == 0 && part_nbytes == 0 && mime->cur_part <= mime->nmtp_parts );
483 } 486 }
484 return ret; 487 return ret;
485 } 488 }
......
...@@ -140,6 +140,7 @@ parseaddr (const char *addr, char *buf, size_t bufsz) ...@@ -140,6 +140,7 @@ parseaddr (const char *addr, char *buf, size_t bufsz)
140 struct token *t, *tok, *last; 140 struct token *t, *tok, *last;
141 struct token *brace = NULL; 141 struct token *brace = NULL;
142 int comment = 0; 142 int comment = 0;
143 int status = 0;
143 144
144 tok = last = NULL; 145 tok = last = NULL;
145 146
...@@ -171,7 +172,10 @@ parseaddr (const char *addr, char *buf, size_t bufsz) ...@@ -171,7 +172,10 @@ parseaddr (const char *addr, char *buf, size_t bufsz)
171 for (; t && t->word[0] != ',' && t->word[0] != '>'; t = t->next) 172 for (; t && t->word[0] != ',' && t->word[0] != '>'; t = t->next)
172 { 173 {
173 if (strlen (t->word) >= bufsz) 174 if (strlen (t->word) >= bufsz)
174 return -1; 175 {
176 status = -1;
177 break;
178 }
175 bufsz -= strlen (t->word); 179 bufsz -= strlen (t->word);
176 strcat (buf, t->word); 180 strcat (buf, t->word);
177 } 181 }
...@@ -183,5 +187,5 @@ parseaddr (const char *addr, char *buf, size_t bufsz) ...@@ -183,5 +187,5 @@ parseaddr (const char *addr, char *buf, size_t bufsz)
183 free (t); 187 free (t);
184 } 188 }
185 189
186 return 0; 190 return status;
187 } 191 }
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
33 #include <mailer0.h> 33 #include <mailer0.h>
34 #include <registrar0.h> 34 #include <registrar0.h>
35 #include <bio.h> 35 #include <bio.h>
36 #include <misc.h>
37 36
38 static int smtp_init (mailer_t); 37 static int smtp_init (mailer_t);
39 38
......