After exchange with Sam Roberts, it should possible to
set a stream on the message and have the message_t do the rfc822 parsing. { message_t mesg = NULL; header_t header = NULL; stream_t stream = NULL; char buffer[512]; off_t off = 0; size_t n = 0; message_create (mesg, NULL); file_stream_crete (&stream, "/home/user/mh/mesg_1"); message_set_stream (mesg, stream, NULL); stream = NULL; message_get_header (mesg, &header); header_get_stream (header, &stream); while (stream_readline (stream, buffer, sizeof buffer, off, &n) == 0 && n > 0) { printf ("%s", buffer); off += n; } message_destroy (&mesg, NULL); } * mailbox/message.c (message_header_fill): New function implements a header if there was a stream set on the message. (message_body_read): Implements the stream_read of body_t of a message if there were a stream set. (message_is_modified): Check if an object was set to message_t and flag it as modified. (message_get_body): If a stream was set on the message create a temporary stream for the body. (message_set_body): Set the message modified. (message_set_header): Set the message modified. (message_set_envelope): Set the message modified. (message_set_attribute): Set the message modified. * mailbox/wicket.c (wicket_destroy): return void. * include/mailutils/auth.h: wicket_destroy () should return void. * mailbox/body.c (body_is_modified): Implemented. (body_clear_modified): Implemented. * mailbox/body.c (body_is_modified): Implemented. (body_clear_modified): Implemented. (_body_get_size0): New function. (_body_get_lines0): New function. (body_get_lines): Call _body_get_lines0(). (body_get_size): Call _body_get_size0(). (body_lines): Fall back on the stream and iterate the entire stream to find the line numbers. (body_size): Fall back on the stream for the size. * mailbox/folder_imap.c: Check if memory_stream_create() succeed and bailout if not. * mailbox/header.c (header_destroy): Free header->mstream. (fill_blurb): Remove redundant code, header_free_cache was doing the same. Implement the code in term of a memory stream to hold the temporary header blurb. (header_write): Implemented. * mailbox/memory_stream.c (_memory_read): Cast the offset to size_t (_memory_readline): Cast the offset to size_t. (_memory_write): Cast the offset to size_t.
Showing
8 changed files
with
294 additions
and
113 deletions
... | @@ -61,14 +61,14 @@ extern int authority_set_authenticate __P ((authority_t, int (*_authenticate) __ | ... | @@ -61,14 +61,14 @@ extern int authority_set_authenticate __P ((authority_t, int (*_authenticate) __ |
61 | struct _wicket; | 61 | struct _wicket; |
62 | typedef struct _wicket *wicket_t; | 62 | typedef struct _wicket *wicket_t; |
63 | 63 | ||
64 | extern int wicket_create __P ((wicket_t *, const char *)); | 64 | extern int wicket_create __P ((wicket_t *, const char *)); |
65 | extern int wicket_destroy __P ((wicket_t *)); | 65 | extern void wicket_destroy __P ((wicket_t *)); |
66 | extern int wicket_set_filename __P ((wicket_t, const char *)); | 66 | extern int wicket_set_filename __P ((wicket_t, const char *)); |
67 | extern int wicket_get_filename __P ((wicket_t, char *, size_t, size_t *)); | 67 | extern int wicket_get_filename __P ((wicket_t, char *, size_t, size_t *)); |
68 | extern int wicket_set_ticket __P ((wicket_t, int (*) | 68 | extern int wicket_set_ticket __P ((wicket_t, int (*) |
69 | __P ((wicket_t, const char *, | 69 | __P ((wicket_t, const char *, |
70 | const char *, ticket_t *)))); | 70 | const char *, ticket_t *)))); |
71 | extern int wicket_get_ticket __P ((wicket_t, ticket_t *, const char *, const char *)); | 71 | extern int wicket_get_ticket __P ((wicket_t, ticket_t *, const char *, const char *)); |
72 | 72 | ||
73 | #ifdef __cplusplus | 73 | #ifdef __cplusplus |
74 | } | 74 | } | ... | ... |
... | @@ -31,6 +31,8 @@ | ... | @@ -31,6 +31,8 @@ |
31 | #include <mailutils/stream.h> | 31 | #include <mailutils/stream.h> |
32 | #include <body0.h> | 32 | #include <body0.h> |
33 | 33 | ||
34 | #define BODY_MODIFIED 0x10000 | ||
35 | |||
34 | static int lazy_create __P ((body_t)); | 36 | static int lazy_create __P ((body_t)); |
35 | static int _body_flush __P ((stream_t)); | 37 | static int _body_flush __P ((stream_t)); |
36 | static int _body_get_fd __P ((stream_t, int *)); | 38 | static int _body_get_fd __P ((stream_t, int *)); |
... | @@ -39,8 +41,12 @@ static int _body_readline __P ((stream_t, char *, size_t, off_t, size_t *)); | ... | @@ -39,8 +41,12 @@ static int _body_readline __P ((stream_t, char *, size_t, off_t, size_t *)); |
39 | static int _body_truncate __P ((stream_t, off_t)); | 41 | static int _body_truncate __P ((stream_t, off_t)); |
40 | static int _body_size __P ((stream_t, off_t *)); | 42 | static int _body_size __P ((stream_t, off_t *)); |
41 | static int _body_write __P ((stream_t, const char *, size_t, off_t, size_t *)); | 43 | static int _body_write __P ((stream_t, const char *, size_t, off_t, size_t *)); |
42 | static int _body_get_size __P ((body_t, size_t *)); | 44 | |
43 | static int _body_get_lines __P ((body_t, size_t *)); | 45 | /* Our own defaults for the body. */ |
46 | static int _body_get_size __P ((body_t, size_t *)); | ||
47 | static int _body_get_lines __P ((body_t, size_t *)); | ||
48 | static int _body_get_size0 __P ((stream_t, size_t *)); | ||
49 | static int _body_get_lines0 __P ((stream_t, size_t *)); | ||
44 | 50 | ||
45 | int | 51 | int |
46 | body_create (body_t *pbody, void *owner) | 52 | body_create (body_t *pbody, void *owner) |
... | @@ -100,14 +106,15 @@ int | ... | @@ -100,14 +106,15 @@ int |
100 | body_is_modified (body_t body) | 106 | body_is_modified (body_t body) |
101 | { | 107 | { |
102 | (void)body; | 108 | (void)body; |
103 | return 0; | 109 | return (body) ? (body->flags & BODY_MODIFIED) : 0; |
104 | } | 110 | } |
105 | 111 | ||
106 | /* FIXME: not implemented. */ | 112 | /* FIXME: not implemented. */ |
107 | int | 113 | int |
108 | body_clear_modified (body_t body) | 114 | body_clear_modified (body_t body) |
109 | { | 115 | { |
110 | (void)body; | 116 | if (body) |
117 | body->flags &= ~BODY_MODIFIED; | ||
111 | return 0; | 118 | return 0; |
112 | } | 119 | } |
113 | 120 | ||
... | @@ -178,11 +185,12 @@ body_set_stream (body_t body, stream_t stream, void *owner) | ... | @@ -178,11 +185,12 @@ body_set_stream (body_t body, stream_t stream, void *owner) |
178 | /* make sure we destroy the old one if it is own by the body */ | 185 | /* make sure we destroy the old one if it is own by the body */ |
179 | stream_destroy (&(body->stream), body); | 186 | stream_destroy (&(body->stream), body); |
180 | body->stream = stream; | 187 | body->stream = stream; |
188 | body->flags |= BODY_MODIFIED; | ||
181 | return 0; | 189 | return 0; |
182 | } | 190 | } |
183 | 191 | ||
184 | int | 192 | int |
185 | body_set_lines (body_t body, int (*_lines)(body_t, size_t *), void *owner) | 193 | body_set_lines (body_t body, int (*_lines)__P ((body_t, size_t *)), void *owner) |
186 | { | 194 | { |
187 | if (body == NULL) | 195 | if (body == NULL) |
188 | return EINVAL; | 196 | return EINVAL; |
... | @@ -199,6 +207,9 @@ body_lines (body_t body, size_t *plines) | ... | @@ -199,6 +207,9 @@ body_lines (body_t body, size_t *plines) |
199 | return EINVAL; | 207 | return EINVAL; |
200 | if (body->_lines) | 208 | if (body->_lines) |
201 | return body->_lines (body, plines); | 209 | return body->_lines (body, plines); |
210 | /* Fall on the stream. */ | ||
211 | if (body->stream) | ||
212 | return _body_get_lines0 (body->stream, plines); | ||
202 | if (plines) | 213 | if (plines) |
203 | *plines = 0; | 214 | *plines = 0; |
204 | return 0; | 215 | return 0; |
... | @@ -211,6 +222,9 @@ body_size (body_t body, size_t *psize) | ... | @@ -211,6 +222,9 @@ body_size (body_t body, size_t *psize) |
211 | return EINVAL; | 222 | return EINVAL; |
212 | if (body->_size) | 223 | if (body->_size) |
213 | return body->_size (body, psize); | 224 | return body->_size (body, psize); |
225 | /* Fall on the stream. */ | ||
226 | if (body->stream) | ||
227 | return _body_get_size0 (body->stream, psize); | ||
214 | if (psize) | 228 | if (psize) |
215 | *psize = 0; | 229 | *psize = 0; |
216 | return 0; | 230 | return 0; |
... | @@ -227,6 +241,8 @@ body_set_size (body_t body, int (*_size)(body_t, size_t*) , void *owner) | ... | @@ -227,6 +241,8 @@ body_set_size (body_t body, int (*_size)(body_t, size_t*) , void *owner) |
227 | return 0; | 241 | return 0; |
228 | } | 242 | } |
229 | 243 | ||
244 | /* Stub function for the body stream. */ | ||
245 | |||
230 | static int | 246 | static int |
231 | _body_get_fd (stream_t stream, int *fd) | 247 | _body_get_fd (stream_t stream, int *fd) |
232 | { | 248 | { |
... | @@ -276,27 +292,40 @@ _body_flush (stream_t stream) | ... | @@ -276,27 +292,40 @@ _body_flush (stream_t stream) |
276 | return stream_flush (body->fstream); | 292 | return stream_flush (body->fstream); |
277 | } | 293 | } |
278 | 294 | ||
295 | /* Default function for the body. */ | ||
279 | static int | 296 | static int |
280 | _body_get_size (body_t body, size_t *plines) | 297 | _body_get_lines (body_t body, size_t *plines) |
298 | { | ||
299 | return _body_get_lines0 (body->fstream, plines); | ||
300 | } | ||
301 | |||
302 | static int | ||
303 | _body_get_size (body_t body, size_t *psize) | ||
304 | { | ||
305 | return _body_get_size0 (body->fstream, psize); | ||
306 | } | ||
307 | |||
308 | static int | ||
309 | _body_get_size0 (stream_t stream, size_t *psize) | ||
281 | { | 310 | { |
282 | off_t off = 0; | 311 | off_t off = 0; |
283 | int status = _body_size (body->stream, &off); | 312 | int status = stream_size (stream, &off); |
284 | if (plines) | 313 | if (psize) |
285 | *plines = off; | 314 | *psize = off; |
286 | return status; | 315 | return status; |
287 | } | 316 | } |
288 | 317 | ||
289 | static int | 318 | static int |
290 | _body_get_lines (body_t body, size_t *plines) | 319 | _body_get_lines0 (stream_t stream, size_t *plines) |
291 | { | 320 | { |
292 | int status = stream_flush (body->fstream); | 321 | int status = stream_flush (stream); |
293 | size_t lines = 0; | 322 | size_t lines = 0; |
294 | if (status == 0) | 323 | if (status == 0) |
295 | { | 324 | { |
296 | char buf[128]; | 325 | char buf[128]; |
297 | size_t n = 0; | 326 | size_t n = 0; |
298 | off_t off = 0; | 327 | off_t off = 0; |
299 | while ((status = stream_readline (body->fstream, buf, sizeof buf, | 328 | while ((status = stream_readline (stream, buf, sizeof buf, |
300 | off, &n)) == 0 && n > 0) | 329 | off, &n)) == 0 && n > 0) |
301 | { | 330 | { |
302 | if (buf[n - 1] == '\n') | 331 | if (buf[n - 1] == '\n') | ... | ... |
... | @@ -434,7 +434,9 @@ folder_imap_open (folder_t folder, int flags) | ... | @@ -434,7 +434,9 @@ folder_imap_open (folder_t folder, int flags) |
434 | { | 434 | { |
435 | CHECK_ERROR (f_imap, ENOMEM); | 435 | CHECK_ERROR (f_imap, ENOMEM); |
436 | } | 436 | } |
437 | memory_stream_create (&f_imap->string.stream); | 437 | status = memory_stream_create (&f_imap->string.stream); |
438 | CHECK_ERROR (f_imap, status); | ||
439 | stream_open (f_imap->string.stream, NULL, 0, MU_STREAM_RDWR); | ||
438 | } | 440 | } |
439 | else | 441 | else |
440 | { | 442 | { | ... | ... |
... | @@ -100,6 +100,9 @@ header_destroy (header_t *ph, void *owner) | ... | @@ -100,6 +100,9 @@ header_destroy (header_t *ph, void *owner) |
100 | 100 | ||
101 | header_free_cache (header); | 101 | header_free_cache (header); |
102 | 102 | ||
103 | if (header->mstream) | ||
104 | stream_destroy (&(header->mstream), NULL); | ||
105 | |||
103 | free (header); | 106 | free (header); |
104 | } | 107 | } |
105 | *ph = NULL; | 108 | *ph = NULL; |
... | @@ -144,7 +147,7 @@ header_parse (header_t header, const char *blurb, int len) | ... | @@ -144,7 +147,7 @@ header_parse (header_t header, const char *blurb, int len) |
144 | return 0; | 147 | return 0; |
145 | 148 | ||
146 | header->blurb_len = len; | 149 | header->blurb_len = len; |
147 | header->blurb = calloc (header->blurb_len + 1, sizeof(char)); | 150 | header->blurb = calloc (1, header->blurb_len + 1); |
148 | if (header->blurb == NULL) | 151 | if (header->blurb == NULL) |
149 | return ENOMEM; | 152 | return ENOMEM; |
150 | memcpy (header->blurb, blurb, header->blurb_len); | 153 | memcpy (header->blurb, blurb, header->blurb_len); |
... | @@ -845,27 +848,11 @@ fill_blurb (header_t header) | ... | @@ -845,27 +848,11 @@ fill_blurb (header_t header) |
845 | { | 848 | { |
846 | int status; | 849 | int status; |
847 | char buf[1024]; | 850 | char buf[1024]; |
848 | char *tbuf; | 851 | size_t nread; |
849 | size_t nread = 0; | ||
850 | size_t i; | ||
851 | 852 | ||
852 | if (header->_fill == NULL) | 853 | if (header->_fill == NULL) |
853 | return 0; | 854 | return 0; |
854 | 855 | ||
855 | /* Free any fast header, since we will load the entire headers. */ | ||
856 | for (i = 0; i < header->fhdr_count; i++) | ||
857 | { | ||
858 | if (header->fhdr[i].fn) | ||
859 | free (header->fhdr[i].fn); | ||
860 | if (header->fhdr[i].fv) | ||
861 | free (header->fhdr[i].fv); | ||
862 | } | ||
863 | if (header->fhdr) | ||
864 | { | ||
865 | free (header->fhdr); | ||
866 | header->fhdr = NULL; | ||
867 | } | ||
868 | |||
869 | /* The entire header is now ours(part of header_t), clear all the | 856 | /* The entire header is now ours(part of header_t), clear all the |
870 | overloading. */ | 857 | overloading. */ |
871 | header_free_cache (header); | 858 | header_free_cache (header); |
... | @@ -875,45 +862,58 @@ fill_blurb (header_t header) | ... | @@ -875,45 +862,58 @@ fill_blurb (header_t header) |
875 | header->_size = NULL; | 862 | header->_size = NULL; |
876 | header->_lines = NULL; | 863 | header->_lines = NULL; |
877 | 864 | ||
865 | if (header->mstream == NULL) | ||
866 | { | ||
867 | status = memory_stream_create (&(header->mstream)); | ||
868 | if (status != 0) | ||
869 | return status; | ||
870 | stream_open (header->mstream, NULL, 0, MU_STREAM_RDWR); | ||
871 | header->stream_len = 0; | ||
872 | } | ||
873 | |||
874 | /* Bring in the entire header. */ | ||
878 | do | 875 | do |
879 | { | 876 | { |
880 | status = header->_fill (header, buf, sizeof (buf), | 877 | nread = 0; |
881 | header->temp_blurb_len, &nread) ; | 878 | status = header->_fill (header, buf, sizeof buf, |
879 | header->stream_len, &nread) ; | ||
882 | if (status != 0) | 880 | if (status != 0) |
883 | { | 881 | { |
884 | if (status != EAGAIN && status != EINTR) | 882 | if (status != EAGAIN && status != EINTR) |
885 | { | 883 | { |
886 | free (header->temp_blurb); | 884 | stream_destroy (&(header->mstream), NULL); |
887 | header->temp_blurb = NULL; | 885 | header->stream_len = 0; |
888 | header->temp_blurb_len = 0; | ||
889 | } | 886 | } |
890 | return status; | 887 | return status; |
891 | } | 888 | } |
892 | if (nread > 0) | 889 | if (nread > 0) |
893 | { | 890 | { |
894 | tbuf = realloc (header->temp_blurb, header->temp_blurb_len + nread); | 891 | status = stream_write (header->mstream, buf, nread, header->stream_len, NULL); |
895 | if (tbuf == NULL) | 892 | if (status != 0) |
896 | { | 893 | { |
897 | free (header->temp_blurb); | 894 | stream_destroy (&(header->mstream), NULL); |
898 | header->temp_blurb = NULL; | 895 | header->stream_len = 0; |
899 | header->temp_blurb_len = 0; | 896 | return status; |
900 | return ENOMEM; | ||
901 | } | 897 | } |
902 | header->temp_blurb = tbuf; | 898 | header->stream_len += nread; |
903 | memcpy (header->temp_blurb + header->temp_blurb_len, buf, nread); | ||
904 | header->temp_blurb_len += nread; | ||
905 | } | 899 | } |
906 | } | 900 | } |
907 | while (nread > 0); | 901 | while (nread > 0); |
908 | 902 | ||
909 | /* parse it. */ | 903 | /* parse it. */ |
910 | status = header_parse (header, header->temp_blurb, header->temp_blurb_len); | 904 | { |
911 | if (header->temp_blurb) | 905 | char *blurb; |
912 | { | 906 | size_t len = header->stream_len; |
913 | free (header->temp_blurb); | 907 | blurb = calloc (1, len + 1); |
914 | header->temp_blurb = NULL; | 908 | if (blurb) |
915 | } | 909 | { |
916 | header->temp_blurb_len = 0; | 910 | stream_read (header->mstream, blurb, len, 0, &len); |
911 | status = header_parse (header, blurb, len); | ||
912 | } | ||
913 | free (blurb); | ||
914 | } | ||
915 | stream_destroy (&header->mstream, NULL); | ||
916 | header->stream_len = 0; | ||
917 | return status; | 917 | return status; |
918 | } | 918 | } |
919 | 919 | ||
... | @@ -922,17 +922,80 @@ header_write (stream_t os, const char *buf, size_t buflen, | ... | @@ -922,17 +922,80 @@ header_write (stream_t os, const char *buf, size_t buflen, |
922 | off_t off, size_t *pnwrite) | 922 | off_t off, size_t *pnwrite) |
923 | { | 923 | { |
924 | header_t header = stream_get_owner (os); | 924 | header_t header = stream_get_owner (os); |
925 | if (os == NULL || header == NULL) | 925 | int status; |
926 | |||
927 | if (header == NULL) | ||
926 | return EINVAL; | 928 | return EINVAL; |
927 | 929 | ||
928 | (void)buf; (void)off; | 930 | if ((size_t)off != header->stream_len) |
929 | if (buflen == 0) | 931 | return ESPIPE; |
930 | return 0; | 932 | |
933 | /* Skip the obvious. */ | ||
934 | if (buf == NULL || *buf == '\0' || buflen == 0) | ||
935 | { | ||
936 | if (pnwrite) | ||
937 | *pnwrite = 0; | ||
938 | return 0; | ||
939 | } | ||
940 | |||
941 | if (header->mstream == NULL) | ||
942 | { | ||
943 | status = memory_stream_create (&(header->mstream)); | ||
944 | if (status != 0) | ||
945 | return status; | ||
946 | stream_open (header->mstream, NULL, 0, MU_STREAM_RDWR); | ||
947 | header->stream_len = 0; | ||
948 | } | ||
949 | |||
950 | status = stream_write (header->mstream, buf, buflen, header->stream_len, &buflen); | ||
951 | if (status != 0) | ||
952 | { | ||
953 | stream_destroy (&header->mstream, NULL); | ||
954 | header->stream_len = 0; | ||
955 | return status; | ||
956 | } | ||
957 | header->stream_len += buflen; | ||
958 | |||
959 | /* We detect an empty line .i.e "^\n$" this signal the end of the | ||
960 | header. */ | ||
961 | if (header->stream_len) | ||
962 | { | ||
963 | int finish = 0; | ||
964 | char nlnl[2]; | ||
965 | nlnl[1] = nlnl[0] = '\0'; | ||
966 | stream_read (header->mstream, nlnl, 1, 0, NULL); | ||
967 | if (nlnl[0] == '\n') | ||
968 | { | ||
969 | finish = 1; | ||
970 | } | ||
971 | else | ||
972 | { | ||
973 | stream_read (header->mstream, nlnl, 2, header->stream_len - 2, NULL); | ||
974 | if (nlnl[0] == '\n' && nlnl[1] == '\n') | ||
975 | { | ||
976 | finish = 1; | ||
977 | } | ||
978 | } | ||
979 | if (finish) | ||
980 | { | ||
981 | char *blurb; | ||
982 | size_t len = header->stream_len; | ||
983 | blurb = calloc (1, len + 1); | ||
984 | if (blurb) | ||
985 | { | ||
986 | stream_read (header->mstream, blurb, len, 0, &len); | ||
987 | status = header_parse (header, blurb, len); | ||
988 | } | ||
989 | free (blurb); | ||
990 | stream_destroy (&header->mstream, NULL); | ||
991 | header->stream_len = 0; | ||
992 | } | ||
993 | } | ||
931 | 994 | ||
932 | if (pnwrite) | 995 | if (pnwrite) |
933 | *pnwrite = 0; | 996 | *pnwrite = buflen; |
997 | return 0; | ||
934 | 998 | ||
935 | return ENOSYS; | ||
936 | } | 999 | } |
937 | 1000 | ||
938 | static int | 1001 | static int | ... | ... |
... | @@ -55,8 +55,8 @@ struct _header | ... | @@ -55,8 +55,8 @@ struct _header |
55 | void *owner; | 55 | void *owner; |
56 | 56 | ||
57 | /* Data. */ | 57 | /* Data. */ |
58 | char *temp_blurb; | 58 | stream_t mstream; |
59 | size_t temp_blurb_len; | 59 | size_t stream_len; |
60 | char *blurb; | 60 | char *blurb; |
61 | size_t blurb_len; | 61 | size_t blurb_len; |
62 | size_t hdr_count; | 62 | size_t hdr_count; |
... | @@ -65,7 +65,7 @@ struct _header | ... | @@ -65,7 +65,7 @@ struct _header |
65 | struct _hdr *fhdr; | 65 | struct _hdr *fhdr; |
66 | int flags; | 66 | int flags; |
67 | 67 | ||
68 | /* Streams. */ | 68 | /* Stream. */ |
69 | stream_t stream; | 69 | stream_t stream; |
70 | int (*_get_value) __P ((header_t, const char *, char *, size_t , size_t *)); | 70 | int (*_get_value) __P ((header_t, const char *, char *, size_t , size_t *)); |
71 | int (*_get_fvalue) __P ((header_t, const char *, char *, size_t , size_t *)); | 71 | int (*_get_fvalue) __P ((header_t, const char *, char *, size_t , size_t *)); | ... | ... |
... | @@ -57,7 +57,7 @@ _memory_read (stream_t stream, char *optr, size_t osize, | ... | @@ -57,7 +57,7 @@ _memory_read (stream_t stream, char *optr, size_t osize, |
57 | { | 57 | { |
58 | struct _memory_stream *mfs = stream_get_owner (stream); | 58 | struct _memory_stream *mfs = stream_get_owner (stream); |
59 | size_t n = 0; | 59 | size_t n = 0; |
60 | if (mfs->ptr != NULL && (offset <= (off_t)mfs->size)) | 60 | if (mfs->ptr != NULL && ((size_t)offset <= mfs->size)) |
61 | { | 61 | { |
62 | n = ((offset + osize) > mfs->size) ? mfs->size - offset : osize; | 62 | n = ((offset + osize) > mfs->size) ? mfs->size - offset : osize; |
63 | memcpy (optr, mfs->ptr + offset, n); | 63 | memcpy (optr, mfs->ptr + offset, n); |
... | @@ -74,7 +74,7 @@ _memory_readline (stream_t stream, char *optr, size_t osize, | ... | @@ -74,7 +74,7 @@ _memory_readline (stream_t stream, char *optr, size_t osize, |
74 | struct _memory_stream *mfs = stream_get_owner (stream); | 74 | struct _memory_stream *mfs = stream_get_owner (stream); |
75 | char *nl; | 75 | char *nl; |
76 | size_t n = 0; | 76 | size_t n = 0; |
77 | if (mfs->ptr && (offset < (off_t)mfs->size)) | 77 | if (mfs->ptr && ((size_t)offset < mfs->size)) |
78 | { | 78 | { |
79 | /* Save space for the null byte. */ | 79 | /* Save space for the null byte. */ |
80 | osize--; | 80 | osize--; |
... | @@ -96,7 +96,7 @@ _memory_write (stream_t stream, const char *iptr, size_t isize, | ... | @@ -96,7 +96,7 @@ _memory_write (stream_t stream, const char *iptr, size_t isize, |
96 | struct _memory_stream *mfs = stream_get_owner (stream); | 96 | struct _memory_stream *mfs = stream_get_owner (stream); |
97 | 97 | ||
98 | /* Bigger we have to realloc. */ | 98 | /* Bigger we have to realloc. */ |
99 | if (mfs->capacity < (offset + isize)) | 99 | if (mfs->capacity < ((size_t)offset + isize)) |
100 | { | 100 | { |
101 | /* Realloc by fixed blocks of 128. */ | 101 | /* Realloc by fixed blocks of 128. */ |
102 | int newsize = MU_STREAM_MEMORY_BLOCKSIZE * | 102 | int newsize = MU_STREAM_MEMORY_BLOCKSIZE * | ... | ... |
... | @@ -35,6 +35,8 @@ | ... | @@ -35,6 +35,8 @@ |
35 | #include <message0.h> | 35 | #include <message0.h> |
36 | #include <mailutils/address.h> | 36 | #include <mailutils/address.h> |
37 | 37 | ||
38 | #define MESSAGE_MODIFIED 0x10000; | ||
39 | |||
38 | static int message_read __P ((stream_t is, char *buf, size_t buflen, | 40 | static int message_read __P ((stream_t is, char *buf, size_t buflen, |
39 | off_t off, size_t *pnread )); | 41 | off_t off, size_t *pnread )); |
40 | static int message_write __P ((stream_t os, const char *buf, size_t buflen, | 42 | static int message_write __P ((stream_t os, const char *buf, size_t buflen, |
... | @@ -45,6 +47,11 @@ static int message_sender __P ((envelope_t envelope, char *buf, size_t len, | ... | @@ -45,6 +47,11 @@ static int message_sender __P ((envelope_t envelope, char *buf, size_t len, |
45 | static int message_date __P ((envelope_t envelope, char *buf, size_t len, | 47 | static int message_date __P ((envelope_t envelope, char *buf, size_t len, |
46 | size_t *pnwrite)); | 48 | size_t *pnwrite)); |
47 | static int message_stream_size __P((stream_t stream, off_t *psize)); | 49 | static int message_stream_size __P((stream_t stream, off_t *psize)); |
50 | static int message_header_fill __P ((header_t header, char *buffer, | ||
51 | size_t buflen, off_t off, | ||
52 | size_t * pnread)); | ||
53 | static int message_body_read __P ((stream_t stream, char *buffer, | ||
54 | size_t n, off_t off, size_t *pn)); | ||
48 | 55 | ||
49 | /* Allocate ressources for the message_t. */ | 56 | /* Allocate ressources for the message_t. */ |
50 | int | 57 | int |
... | @@ -168,6 +175,7 @@ message_is_modified (message_t msg) | ... | @@ -168,6 +175,7 @@ message_is_modified (message_t msg) |
168 | mod |= header_is_modified (msg->header); | 175 | mod |= header_is_modified (msg->header); |
169 | mod |= attribute_is_modified (msg->attribute); | 176 | mod |= attribute_is_modified (msg->attribute); |
170 | mod |= body_is_modified (msg->body); | 177 | mod |= body_is_modified (msg->body); |
178 | mod |= msg->flags; | ||
171 | } | 179 | } |
172 | return mod; | 180 | return mod; |
173 | } | 181 | } |
... | @@ -183,6 +191,7 @@ message_clear_modified (message_t msg) | ... | @@ -183,6 +191,7 @@ message_clear_modified (message_t msg) |
183 | attribute_clear_modified (msg->attribute); | 191 | attribute_clear_modified (msg->attribute); |
184 | if (msg->body) | 192 | if (msg->body) |
185 | body_clear_modified (msg->body); | 193 | body_clear_modified (msg->body); |
194 | msg->flags &= ~MESSAGE_MODIFIED; | ||
186 | } | 195 | } |
187 | return 0; | 196 | return 0; |
188 | } | 197 | } |
... | @@ -220,6 +229,13 @@ message_get_header (message_t msg, header_t *phdr) | ... | @@ -220,6 +229,13 @@ message_get_header (message_t msg, header_t *phdr) |
220 | int status = header_create (&header, NULL, 0, msg); | 229 | int status = header_create (&header, NULL, 0, msg); |
221 | if (status != 0) | 230 | if (status != 0) |
222 | return status; | 231 | return status; |
232 | if (msg->stream) | ||
233 | { | ||
234 | /* Was it created by us? */ | ||
235 | message_t mesg = stream_get_owner (msg->stream); | ||
236 | if (mesg != msg) | ||
237 | header_set_fill (header, message_header_fill, msg); | ||
238 | } | ||
223 | msg->header = header; | 239 | msg->header = header; |
224 | } | 240 | } |
225 | *phdr = msg->header; | 241 | *phdr = msg->header; |
... | @@ -238,6 +254,7 @@ message_set_header (message_t msg, header_t hdr, void *owner) | ... | @@ -238,6 +254,7 @@ message_set_header (message_t msg, header_t hdr, void *owner) |
238 | if (msg->header) | 254 | if (msg->header) |
239 | header_destroy (&(msg->header), msg); | 255 | header_destroy (&(msg->header), msg); |
240 | msg->header = hdr; | 256 | msg->header = hdr; |
257 | msg->flags |= MESSAGE_MODIFIED; | ||
241 | return 0; | 258 | return 0; |
242 | } | 259 | } |
243 | 260 | ||
... | @@ -254,6 +271,26 @@ message_get_body (message_t msg, body_t *pbody) | ... | @@ -254,6 +271,26 @@ message_get_body (message_t msg, body_t *pbody) |
254 | int status = body_create (&body, msg); | 271 | int status = body_create (&body, msg); |
255 | if (status != 0) | 272 | if (status != 0) |
256 | return status; | 273 | return status; |
274 | /* If a stream is already set use it to create the body stream. */ | ||
275 | if (msg->stream) | ||
276 | { | ||
277 | /* Was it created by us? */ | ||
278 | message_t mesg = stream_get_owner (msg->stream); | ||
279 | if (mesg != msg) | ||
280 | { | ||
281 | stream_t stream; | ||
282 | int flags = 0; | ||
283 | stream_get_flags (msg->stream, &flags); | ||
284 | if ((status = stream_create (&stream, flags, body)) != 0) | ||
285 | { | ||
286 | body_destroy (&body, msg); | ||
287 | return status; | ||
288 | } | ||
289 | stream_set_read (stream, message_body_read, body); | ||
290 | stream_setbufsiz (stream, 128); | ||
291 | body_set_stream (body, stream, msg); | ||
292 | } | ||
293 | } | ||
257 | msg->body = body; | 294 | msg->body = body; |
258 | } | 295 | } |
259 | *pbody = msg->body; | 296 | *pbody = msg->body; |
... | @@ -272,6 +309,7 @@ message_set_body (message_t msg, body_t body, void *owner) | ... | @@ -272,6 +309,7 @@ message_set_body (message_t msg, body_t body, void *owner) |
272 | if (msg->body) | 309 | if (msg->body) |
273 | body_destroy (&(msg->body), msg); | 310 | body_destroy (&(msg->body), msg); |
274 | msg->body = body; | 311 | msg->body = body; |
312 | msg->flags |= MESSAGE_MODIFIED; | ||
275 | return 0; | 313 | return 0; |
276 | } | 314 | } |
277 | 315 | ||
... | @@ -287,6 +325,7 @@ message_set_stream (message_t msg, stream_t stream, void *owner) | ... | @@ -287,6 +325,7 @@ message_set_stream (message_t msg, stream_t stream, void *owner) |
287 | if (msg->stream) | 325 | if (msg->stream) |
288 | stream_destroy (&(msg->stream), msg); | 326 | stream_destroy (&(msg->stream), msg); |
289 | msg->stream = stream; | 327 | msg->stream = stream; |
328 | msg->flags |= MESSAGE_MODIFIED; | ||
290 | return 0; | 329 | return 0; |
291 | } | 330 | } |
292 | 331 | ||
... | @@ -411,6 +450,7 @@ message_set_envelope (message_t msg, envelope_t envelope, void *owner) | ... | @@ -411,6 +450,7 @@ message_set_envelope (message_t msg, envelope_t envelope, void *owner) |
411 | if (msg->envelope) | 450 | if (msg->envelope) |
412 | envelope_destroy (&(msg->envelope), msg); | 451 | envelope_destroy (&(msg->envelope), msg); |
413 | msg->envelope = envelope; | 452 | msg->envelope = envelope; |
453 | msg->flags |= MESSAGE_MODIFIED; | ||
414 | return 0; | 454 | return 0; |
415 | } | 455 | } |
416 | 456 | ||
... | @@ -442,6 +482,7 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner) | ... | @@ -442,6 +482,7 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner) |
442 | if (msg->attribute) | 482 | if (msg->attribute) |
443 | attribute_destroy (&(msg->attribute), owner); | 483 | attribute_destroy (&(msg->attribute), owner); |
444 | msg->attribute = attribute; | 484 | msg->attribute = attribute; |
485 | msg->flags |= MESSAGE_MODIFIED; | ||
445 | return 0; | 486 | return 0; |
446 | } | 487 | } |
447 | 488 | ||
... | @@ -666,6 +707,7 @@ message_get_observable (message_t msg, observable_t *pobservable) | ... | @@ -666,6 +707,7 @@ message_get_observable (message_t msg, observable_t *pobservable) |
666 | return 0; | 707 | return 0; |
667 | } | 708 | } |
668 | 709 | ||
710 | /* Implements the stream_read () on the message stream. */ | ||
669 | static int | 711 | static int |
670 | message_read (stream_t is, char *buf, size_t buflen, | 712 | message_read (stream_t is, char *buf, size_t buflen, |
671 | off_t off, size_t *pnread ) | 713 | off_t off, size_t *pnread ) |
... | @@ -703,6 +745,7 @@ message_read (stream_t is, char *buf, size_t buflen, | ... | @@ -703,6 +745,7 @@ message_read (stream_t is, char *buf, size_t buflen, |
703 | return 0; | 745 | return 0; |
704 | } | 746 | } |
705 | 747 | ||
748 | /* Implements the stream_write () on the message stream. */ | ||
706 | static int | 749 | static int |
707 | message_write (stream_t os, const char *buf, size_t buflen, | 750 | message_write (stream_t os, const char *buf, size_t buflen, |
708 | off_t off, size_t *pnwrite) | 751 | off_t off, size_t *pnwrite) |
... | @@ -715,7 +758,7 @@ message_write (stream_t os, const char *buf, size_t buflen, | ... | @@ -715,7 +758,7 @@ message_write (stream_t os, const char *buf, size_t buflen, |
715 | return EINVAL; | 758 | return EINVAL; |
716 | 759 | ||
717 | /* Skip the obvious. */ | 760 | /* Skip the obvious. */ |
718 | if (buf == NULL || *buf == '\0' || buflen == 0) | 761 | if (buf == NULL || buflen == 0) |
719 | { | 762 | { |
720 | if (pnwrite) | 763 | if (pnwrite) |
721 | *pnwrite = 0; | 764 | *pnwrite = 0; |
... | @@ -726,39 +769,21 @@ message_write (stream_t os, const char *buf, size_t buflen, | ... | @@ -726,39 +769,21 @@ message_write (stream_t os, const char *buf, size_t buflen, |
726 | { | 769 | { |
727 | size_t len; | 770 | size_t len; |
728 | char *nl; | 771 | char *nl; |
729 | char *thdr; | 772 | header_t header = NULL; |
773 | stream_t hstream = NULL; | ||
774 | message_get_header (msg, &header); | ||
775 | header_get_stream (header, &hstream); | ||
730 | while (!msg->hdr_done && (nl = memchr (buf, '\n', buflen)) != NULL) | 776 | while (!msg->hdr_done && (nl = memchr (buf, '\n', buflen)) != NULL) |
731 | { | 777 | { |
732 | len = nl - buf + 1; | 778 | len = nl - buf + 1; |
733 | /* Allocate more buffer to hold the header. */ | 779 | status = stream_write (hstream, buf, len, msg->hdr_buflen, NULL); |
734 | thdr = realloc (msg->hdr_buf, msg->hdr_buflen + len); | 780 | if (status != 0) |
735 | if (thdr == NULL) | 781 | return status; |
736 | { | ||
737 | free (msg->hdr_buf); | ||
738 | msg->hdr_buf = NULL; | ||
739 | msg->hdr_buflen = 0; | ||
740 | return ENOMEM; | ||
741 | } | ||
742 | else | ||
743 | msg->hdr_buf = thdr; | ||
744 | memcpy (msg->hdr_buf + msg->hdr_buflen, buf, len); | ||
745 | msg->hdr_buflen += len; | 782 | msg->hdr_buflen += len; |
746 | /* We detect an empty line .i.e "^\n$" this signal the end of the | 783 | /* We detect an empty line .i.e "^\n$" this signal the end of the |
747 | header. */ | 784 | header. */ |
748 | if (buf == nl) | 785 | if (buf == nl) |
749 | { | 786 | msg->hdr_done = 1; |
750 | header_destroy (&(msg->header), msg); | ||
751 | status = header_create (&(msg->header), msg->hdr_buf, | ||
752 | msg->hdr_buflen, msg); | ||
753 | free (msg->hdr_buf); | ||
754 | msg->hdr_buf = NULL; | ||
755 | if (status != 0) | ||
756 | { | ||
757 | msg->hdr_buflen = 0; | ||
758 | return status; | ||
759 | } | ||
760 | msg->hdr_done = 1; | ||
761 | } | ||
762 | buf = nl + 1; | 787 | buf = nl + 1; |
763 | buflen -= len; | 788 | buflen -= len; |
764 | } | 789 | } |
... | @@ -767,17 +792,13 @@ message_write (stream_t os, const char *buf, size_t buflen, | ... | @@ -767,17 +792,13 @@ message_write (stream_t os, const char *buf, size_t buflen, |
767 | /* Message header is not complete but was not a full line. */ | 792 | /* Message header is not complete but was not a full line. */ |
768 | if (!msg->hdr_done && buflen > 0) | 793 | if (!msg->hdr_done && buflen > 0) |
769 | { | 794 | { |
770 | char *thdr = realloc (msg->hdr_buf, msg->hdr_buflen + buflen); | 795 | header_t header = NULL; |
771 | if (thdr == NULL) | 796 | stream_t hstream = NULL; |
772 | { | 797 | message_get_header (msg, &header); |
773 | free (msg->hdr_buf); | 798 | header_get_stream (header, &hstream); |
774 | msg->hdr_buf = NULL; | 799 | status = stream_write (hstream, buf, buflen, msg->hdr_buflen, NULL); |
775 | msg->hdr_buflen = 0; | 800 | if (status != 0) |
776 | return ENOMEM; | 801 | return status; |
777 | } | ||
778 | else | ||
779 | msg->hdr_buf = thdr; | ||
780 | memcpy (msg->hdr_buf + msg->hdr_buflen, buf, buflen); | ||
781 | msg->hdr_buflen += buflen; | 802 | msg->hdr_buflen += buflen; |
782 | buflen = 0; | 803 | buflen = 0; |
783 | } | 804 | } |
... | @@ -806,6 +827,7 @@ message_write (stream_t os, const char *buf, size_t buflen, | ... | @@ -806,6 +827,7 @@ message_write (stream_t os, const char *buf, size_t buflen, |
806 | return status; | 827 | return status; |
807 | } | 828 | } |
808 | 829 | ||
830 | /* Implements the stream_get_fd () on the message stream. */ | ||
809 | static int | 831 | static int |
810 | message_get_fd (stream_t stream, int *pfd) | 832 | message_get_fd (stream_t stream, int *pfd) |
811 | { | 833 | { |
... | @@ -831,7 +853,8 @@ message_get_fd (stream_t stream, int *pfd) | ... | @@ -831,7 +853,8 @@ message_get_fd (stream_t stream, int *pfd) |
831 | return stream_get_fd (is, pfd); | 853 | return stream_get_fd (is, pfd); |
832 | } | 854 | } |
833 | 855 | ||
834 | int | 856 | /* Implements the stream_stream_size () on the message stream. */ |
857 | static int | ||
835 | message_stream_size (stream_t stream, off_t *psize) | 858 | message_stream_size (stream_t stream, off_t *psize) |
836 | { | 859 | { |
837 | message_t msg = stream_get_owner (stream); | 860 | message_t msg = stream_get_owner (stream); |
... | @@ -920,3 +943,66 @@ message_sender (envelope_t envelope, char *buf, size_t len, size_t *pnwrite) | ... | @@ -920,3 +943,66 @@ message_sender (envelope_t envelope, char *buf, size_t len, size_t *pnwrite) |
920 | *pnwrite = n; | 943 | *pnwrite = n; |
921 | return 0; | 944 | return 0; |
922 | } | 945 | } |
946 | |||
947 | static int | ||
948 | message_header_fill (header_t header, char *buffer, size_t buflen, | ||
949 | off_t off, size_t * pnread) | ||
950 | { | ||
951 | int status = 0; | ||
952 | message_t msg = header_get_owner (header); | ||
953 | stream_t stream = NULL; | ||
954 | size_t nread = 0; | ||
955 | |||
956 | /* Noop. */ | ||
957 | if (buffer == NULL || buflen == 0) | ||
958 | { | ||
959 | if (pnread) | ||
960 | *pnread = nread; | ||
961 | return 0; | ||
962 | } | ||
963 | |||
964 | if (!msg->hdr_done) | ||
965 | { | ||
966 | status = message_get_stream (msg, &stream); | ||
967 | if (status == 0) | ||
968 | { | ||
969 | /* Position the file pointer and the buffer. */ | ||
970 | status = stream_readline (stream, buffer, buflen, off, &nread); | ||
971 | /* Detect the end of the headers. */ | ||
972 | if (nread && buffer[0] == '\n' && buffer[1] == '\0') | ||
973 | { | ||
974 | msg->hdr_done = 1; | ||
975 | } | ||
976 | msg->hdr_buflen += nread; | ||
977 | } | ||
978 | } | ||
979 | |||
980 | if (pnread) | ||
981 | *pnread = nread; | ||
982 | |||
983 | return status; | ||
984 | } | ||
985 | |||
986 | static int | ||
987 | message_body_read (stream_t stream, char *buffer, size_t n, off_t off, | ||
988 | size_t *pn) | ||
989 | { | ||
990 | body_t body = stream_get_owner (stream); | ||
991 | message_t msg = body_get_owner (body); | ||
992 | size_t nread = 0; | ||
993 | header_t header = NULL; | ||
994 | stream_t bstream = NULL; | ||
995 | size_t size = 0; | ||
996 | int status; | ||
997 | |||
998 | message_get_header (msg, &header); | ||
999 | status = header_size (msg->header, &size); | ||
1000 | if (status == 0) | ||
1001 | { | ||
1002 | message_get_stream (msg, &bstream); | ||
1003 | status = stream_read (bstream, buffer, n, size + off, &nread); | ||
1004 | } | ||
1005 | if (pn) | ||
1006 | *pn = nread; | ||
1007 | return status; | ||
1008 | } | ... | ... |
... | @@ -27,6 +27,7 @@ | ... | @@ -27,6 +27,7 @@ |
27 | #include <unistd.h> | 27 | #include <unistd.h> |
28 | #include <ctype.h> | 28 | #include <ctype.h> |
29 | 29 | ||
30 | #include <mailutils/mutil.h> | ||
30 | #include <auth0.h> | 31 | #include <auth0.h> |
31 | 32 | ||
32 | struct myticket_data | 33 | struct myticket_data |
... | @@ -56,7 +57,7 @@ wicket_create (wicket_t *pwicket, const char *filename) | ... | @@ -56,7 +57,7 @@ wicket_create (wicket_t *pwicket, const char *filename) |
56 | return 0; | 57 | return 0; |
57 | } | 58 | } |
58 | 59 | ||
59 | int | 60 | void |
60 | wicket_destroy (wicket_t *pwicket) | 61 | wicket_destroy (wicket_t *pwicket) |
61 | { | 62 | { |
62 | if (pwicket && *pwicket) | 63 | if (pwicket && *pwicket) |
... | @@ -96,13 +97,13 @@ wicket_set_filename (wicket_t wicket, const char *filename) | ... | @@ -96,13 +97,13 @@ wicket_set_filename (wicket_t wicket, const char *filename) |
96 | } | 97 | } |
97 | 98 | ||
98 | int | 99 | int |
99 | wicket_set_ticket (wicket_t wicket, int _get_ticket | 100 | wicket_set_ticket (wicket_t wicket, int get_ticket |
100 | __P ((wicket_t, const char *, const char *, ticket_t *))) | 101 | __P ((wicket_t, const char *, const char *, ticket_t *))) |
101 | { | 102 | { |
102 | if (wicket == NULL) | 103 | if (wicket == NULL) |
103 | return EINVAL; | 104 | return EINVAL; |
104 | 105 | ||
105 | wicket->_get_ticket = _get_ticket; | 106 | wicket->_get_ticket = get_ticket; |
106 | return 0; | 107 | return 0; |
107 | } | 108 | } |
108 | 109 | ... | ... |
-
Please register or sign in to post a comment