The big change: For getting the header we use "TOP # 0" but since TOP is an
optionnal command, we fallback to RETR and ignore the body part. This ugly and wastefull and it made the code unnecessary complexe. But fortunately I do not know of any POP server that does not have TOP. It's a mess. The other stuff was little cleanups.
Showing
10 changed files
with
217 additions
and
96 deletions
1 | The current maintainer Alain Magloire <alainm@rcsm.ece.mcgill.ca> | 1 | The current maintainer Alain Magloire <alainm@gnu.org> |
2 | 2 | ||
3 | Brian Edmond <briane@qnx.com> | ||
4 | Dave Inglis <dinglis@qnx.com> | ||
3 | Jakob Kaivo <jkaivo@ndn.net> | 5 | Jakob Kaivo <jkaivo@ndn.net> |
4 | Jeff Bailey <jbailey@gnu.org> | 6 | Jeff Bailey <jbailey@gnu.org> |
5 | Sean 'Shaleh' Perry <shaleh@debian.org> | 7 | Sean 'Shaleh' Perry <shaleh@debian.org> |
8 | ... | ... |
... | @@ -47,13 +47,11 @@ extern int body_get_filename __P ((body_t, char *, size_t, size_t *)); | ... | @@ -47,13 +47,11 @@ extern int body_get_filename __P ((body_t, char *, size_t, size_t *)); |
47 | extern int body_set_filename __P ((body_t, const char*)); | 47 | extern int body_set_filename __P ((body_t, const char*)); |
48 | 48 | ||
49 | extern int body_size __P ((body_t, size_t*)); | 49 | extern int body_size __P ((body_t, size_t*)); |
50 | extern int body_set_size __P ((body_t, | 50 | extern int body_set_size __P ((body_t, int (*_size) |
51 | int (*_size) __P ((body_t, size_t*)), | 51 | __P ((body_t, size_t*)), void *owner)); |
52 | void *owner)); | ||
53 | extern int body_lines __P ((body_t, size_t *)); | 52 | extern int body_lines __P ((body_t, size_t *)); |
54 | extern int body_set_lines __P ((body_t, | 53 | extern int body_set_lines __P ((body_t, int (*_lines) |
55 | int (*_lines) __P ((body_t, size_t*)), | 54 | __P ((body_t, size_t*)), void *owner)); |
56 | void *owner)); | ||
57 | 55 | ||
58 | #ifdef _cplusplus | 56 | #ifdef _cplusplus |
59 | } | 57 | } | ... | ... |
... | @@ -70,24 +70,29 @@ typedef struct _header * header_t; | ... | @@ -70,24 +70,29 @@ typedef struct _header * header_t; |
70 | extern int header_create __P ((header_t *, const char *, | 70 | extern int header_create __P ((header_t *, const char *, |
71 | size_t, void *)); | 71 | size_t, void *)); |
72 | extern void header_destroy __P ((header_t *, void *)); | 72 | extern void header_destroy __P ((header_t *, void *)); |
73 | |||
73 | extern int header_set_value __P ((header_t, const char *, | 74 | extern int header_set_value __P ((header_t, const char *, |
74 | const char *, int)); | 75 | const char *, int)); |
76 | extern int header_set_set_value __P ((header_t, int (*_set_value) | ||
77 | __P ((header_t, const char *, | ||
78 | const char *, int)), void *)); | ||
79 | |||
75 | extern int header_get_value __P ((header_t, const char *, char *, | 80 | extern int header_get_value __P ((header_t, const char *, char *, |
76 | size_t, size_t *)); | 81 | size_t, size_t *)); |
77 | extern int header_get_stream __P ((header_t, stream_t *)); | 82 | extern int header_set_get_value __P ((header_t, int (*_get_value) |
78 | extern int header_size __P ((header_t, size_t *)); | 83 | __P ((header_t, const char *, char *, |
79 | extern int header_lines __P ((header_t, size_t *)); | 84 | size_t, size_t *)), void *)); |
80 | 85 | ||
86 | extern int header_get_stream __P ((header_t, stream_t *)); | ||
81 | extern int header_set_stream __P ((header_t, stream_t, void *)); | 87 | extern int header_set_stream __P ((header_t, stream_t, void *)); |
82 | 88 | ||
83 | extern int header_set_set_value __P ((header_t, int (*_set_value) | 89 | extern int header_size __P ((header_t, size_t *)); |
84 | __P ((header_t, const char *, | 90 | extern int header_set_size __P ((header_t, int (*_size) |
85 | const char *, int)), | 91 | __P ((header_t, size_t *)), void *)); |
86 | void *)); | 92 | |
87 | extern int header_set_get_value __P ((header_t, int (*_get_value) | 93 | extern int header_lines __P ((header_t, size_t *)); |
88 | __P ((header_t, const char *, | 94 | extern int header_set_lines __P ((header_t, int (*_lines) |
89 | char *, size_t, size_t *)), | 95 | __P ((header_t, size_t *)), void *)); |
90 | void *)); | ||
91 | 96 | ||
92 | #ifdef _cplusplus | 97 | #ifdef _cplusplus |
93 | } | 98 | } | ... | ... |
... | @@ -45,49 +45,59 @@ typedef struct _message *message_t; | ... | @@ -45,49 +45,59 @@ typedef struct _message *message_t; |
45 | * header_t, body_t, and its attribute_t. | 45 | * header_t, body_t, and its attribute_t. |
46 | */ | 46 | */ |
47 | 47 | ||
48 | extern int message_create __P ((message_t *, void *owner)); | 48 | extern int message_create __P ((message_t *, void *owner)); |
49 | extern void message_destroy __P ((message_t *, void *owner)); | 49 | extern void message_destroy __P ((message_t *, void *owner)); |
50 | 50 | ||
51 | extern int message_get_header __P ((message_t, header_t *)); | 51 | extern int message_get_header __P ((message_t, header_t *)); |
52 | extern int message_set_header __P ((message_t, header_t, void *owner)); | 52 | extern int message_set_header __P ((message_t, header_t, void *owner)); |
53 | 53 | ||
54 | extern int message_get_body __P ((message_t, body_t *)); | 54 | extern int message_get_body __P ((message_t, body_t *)); |
55 | extern int message_set_body __P ((message_t, body_t, void *owner)); | 55 | extern int message_set_body __P ((message_t, body_t, void *owner)); |
56 | 56 | ||
57 | extern int message_get_stream __P ((message_t, stream_t *)); | 57 | extern int message_get_stream __P ((message_t, stream_t *)); |
58 | 58 | extern int message_set_stream __P ((message_t, stream_t, void *owner)); | |
59 | extern int message_is_mime __P ((message_t)); | 59 | |
60 | 60 | extern int message_is_multipart __P ((message_t, int *)); | |
61 | extern int message_size __P ((message_t, size_t *)); | 61 | extern int message_set_is_multipart __P ((message_t, int (*_is_multipart) |
62 | extern int message_lines __P ((message_t, size_t *)); | 62 | __P ((message_t, int *)), void *)); |
63 | 63 | ||
64 | extern int message_from __P ((message_t, char *, size_t, size_t *)); | 64 | extern int message_size __P ((message_t, size_t *)); |
65 | extern int message_set_from __P ((message_t, | 65 | extern int message_set_size __P ((message_t, int (*_size) |
66 | int (*_from) __P ((message_t, char *, | 66 | __P ((message_t, size_t *)), |
67 | size_t, size_t *)), | 67 | void *owner)); |
68 | void *owner)); | 68 | |
69 | extern int message_received __P ((message_t, char *, size_t, size_t *)); | 69 | extern int message_lines __P ((message_t, size_t *)); |
70 | extern int message_set_received __P ((message_t, int (*_received) | 70 | extern int message_set_lines __P ((message_t, int (*_lines) |
71 | __P ((message_t, char *, size_t, | 71 | __P ((message_t, size_t *)), |
72 | size_t *)), void *owner)); | 72 | void *owner)); |
73 | 73 | ||
74 | extern int message_get_attribute __P ((message_t, attribute_t *)); | 74 | extern int message_from __P ((message_t, char *, size_t, size_t *)); |
75 | extern int message_set_attribute __P ((message_t, attribute_t, void *owner)); | 75 | extern int message_set_from __P ((message_t, int (*_from) |
76 | 76 | __P ((message_t, char *, size_t, | |
77 | extern int message_get_num_parts __P ((message_t, size_t *nparts)); | 77 | size_t *)), void *owner)); |
78 | extern int message_set_get_num_parts __P ((message_t, int (*_getNum_parts) | 78 | |
79 | __P ((message_t, size_t *)), | 79 | extern int message_received __P ((message_t, char *, size_t, size_t *)); |
80 | void *owner)); | 80 | extern int message_set_received __P ((message_t, int (*_received) |
81 | 81 | __P ((message_t, char *, size_t, | |
82 | extern int message_get_part __P ((message_t, size_t part, message_t *msg)); | 82 | size_t *)), void *owner)); |
83 | extern int message_set_get_part __P ((message_t, int (*_get_part) | 83 | |
84 | __P ((message_t, size_t, message_t *)), | 84 | extern int message_get_attribute __P ((message_t, attribute_t *)); |
85 | void *owner)); | 85 | extern int message_set_attribute __P ((message_t, attribute_t, void *)); |
86 | 86 | ||
87 | extern int message_get_uidl __P ((message_t, char *buffer, size_t, size_t *)); | 87 | extern int message_get_num_parts __P ((message_t, size_t *nparts)); |
88 | extern int message_set_uidl __P ((message_t, int (*_get_uidl) | 88 | extern int message_set_get_num_parts __P ((message_t, int (*_get_num_parts) |
89 | __P ((message_t, char *, size_t, size_t *)), | 89 | __P ((message_t, size_t *)), |
90 | void *owner)); | 90 | void *owner)); |
91 | |||
92 | extern int message_get_part __P ((message_t, size_t, message_t *)); | ||
93 | extern int message_set_get_part __P ((message_t, int (*_get_part) | ||
94 | __P ((message_t, size_t, | ||
95 | message_t *)), void *owner)); | ||
96 | |||
97 | extern int message_get_uidl __P ((message_t, char *, size_t, size_t *)); | ||
98 | extern int message_set_uidl __P ((message_t, int (*_get_uidl) | ||
99 | __P ((message_t, char *, size_t, | ||
100 | size_t *)), void *owner)); | ||
91 | 101 | ||
92 | /* events */ | 102 | /* events */ |
93 | #define MU_EVT_MSG_DESTROY 32 | 103 | #define MU_EVT_MSG_DESTROY 32 | ... | ... |
... | @@ -198,7 +198,8 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) | ... | @@ -198,7 +198,8 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) |
198 | if (header == NULL || fn == NULL || fv == NULL) | 198 | if (header == NULL || fn == NULL || fv == NULL) |
199 | return EINVAL; | 199 | return EINVAL; |
200 | 200 | ||
201 | if (header->_set_value != NULL) | 201 | /* Overload. */ |
202 | if (header->_set_value) | ||
202 | return header->_set_value (header, fn, fv, replace); | 203 | return header->_set_value (header, fn, fv, replace); |
203 | 204 | ||
204 | /* Try to fill out the buffer, if we know how. */ | 205 | /* Try to fill out the buffer, if we know how. */ |
... | @@ -268,7 +269,8 @@ header_get_value (header_t header, const char *name, char *buffer, | ... | @@ -268,7 +269,8 @@ header_get_value (header_t header, const char *name, char *buffer, |
268 | if (header == NULL || name == NULL) | 269 | if (header == NULL || name == NULL) |
269 | return EINVAL; | 270 | return EINVAL; |
270 | 271 | ||
271 | if (header->_get_value != NULL) | 272 | /* Overload. */ |
273 | if (header->_get_value) | ||
272 | return header->_get_value (header, name, buffer, buflen, pn); | 274 | return header->_get_value (header, name, buffer, buflen, pn); |
273 | 275 | ||
274 | /* Try to fill out the buffer, if we know how. */ | 276 | /* Try to fill out the buffer, if we know how. */ |
... | @@ -320,27 +322,36 @@ header_get_value (header_t header, const char *name, char *buffer, | ... | @@ -320,27 +322,36 @@ header_get_value (header_t header, const char *name, char *buffer, |
320 | if (pn) | 322 | if (pn) |
321 | *pn = total; | 323 | *pn = total; |
322 | 324 | ||
323 | /* Check if they provided a hook. */ | ||
324 | if (total == 0) | 325 | if (total == 0) |
325 | { | 326 | err = ENOENT; |
326 | err = ENOENT; | 327 | |
327 | if (header->_get_value != NULL) | ||
328 | err = header->_get_value (header, name, buffer, buflen, pn); | ||
329 | /* Success. Cache it locally. */ | ||
330 | if (err == 0) | ||
331 | header_set_value (header, name, buffer, 0); | ||
332 | } | ||
333 | return err; | 328 | return err; |
334 | } | 329 | } |
335 | 330 | ||
336 | int | 331 | int |
332 | header_set_lines (header_t header, int (*_lines) | ||
333 | (header_t, size_t *), void *owner) | ||
334 | { | ||
335 | if (header == NULL) | ||
336 | return EINVAL; | ||
337 | if (header->owner != owner) | ||
338 | return EACCES; | ||
339 | header->_lines = _lines; | ||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | int | ||
337 | header_lines (header_t header, size_t *plines) | 344 | header_lines (header_t header, size_t *plines) |
338 | { | 345 | { |
339 | int n; | 346 | int n; |
340 | size_t lines = 0; | 347 | size_t lines = 0; |
341 | if (header == NULL) | 348 | if (header == NULL || plines == NULL) |
342 | return EINVAL; | 349 | return EINVAL; |
343 | 350 | ||
351 | /* Overload. */ | ||
352 | if (header->_lines) | ||
353 | return header->_lines (header, plines); | ||
354 | |||
344 | /* Try to fill out the buffer, if we know how. */ | 355 | /* Try to fill out the buffer, if we know how. */ |
345 | if (header->blurb == NULL) | 356 | if (header->blurb == NULL) |
346 | { | 357 | { |
... | @@ -360,11 +371,27 @@ header_lines (header_t header, size_t *plines) | ... | @@ -360,11 +371,27 @@ header_lines (header_t header, size_t *plines) |
360 | } | 371 | } |
361 | 372 | ||
362 | int | 373 | int |
363 | header_size (header_t header, size_t *pnum) | 374 | header_set_size (header_t header, int (*_size) |
375 | (header_t, size_t *), void *owner) | ||
376 | { | ||
377 | if (header == NULL) | ||
378 | return EINVAL; | ||
379 | if (header->owner != owner) | ||
380 | return EACCES; | ||
381 | header->_size = _size; | ||
382 | return 0; | ||
383 | } | ||
384 | |||
385 | int | ||
386 | header_size (header_t header, size_t *psize) | ||
364 | { | 387 | { |
365 | if (header == NULL) | 388 | if (header == NULL) |
366 | return EINVAL; | 389 | return EINVAL; |
367 | 390 | ||
391 | /* Overload. */ | ||
392 | if (header->_size) | ||
393 | return header->_size (header, psize); | ||
394 | |||
368 | /* Try to fill out the buffer, if we know how. */ | 395 | /* Try to fill out the buffer, if we know how. */ |
369 | if (header->blurb == NULL) | 396 | if (header->blurb == NULL) |
370 | { | 397 | { |
... | @@ -373,8 +400,8 @@ header_size (header_t header, size_t *pnum) | ... | @@ -373,8 +400,8 @@ header_size (header_t header, size_t *pnum) |
373 | return err; | 400 | return err; |
374 | } | 401 | } |
375 | 402 | ||
376 | if (pnum) | 403 | if (psize) |
377 | *pnum = header->blurb_len; | 404 | *psize = header->blurb_len; |
378 | return 0; | 405 | return 0; |
379 | } | 406 | } |
380 | 407 | ... | ... |
... | @@ -43,6 +43,9 @@ mailbox_create (mailbox_t *pmbox, const char *name, int id) | ... | @@ -43,6 +43,9 @@ mailbox_create (mailbox_t *pmbox, const char *name, int id) |
43 | struct mailbox_registrar *mreg; | 43 | struct mailbox_registrar *mreg; |
44 | url_t url = NULL; | 44 | url_t url = NULL; |
45 | 45 | ||
46 | if (pmbox == NULL) | ||
47 | return EINVAL; | ||
48 | |||
46 | url_create (&url, name); | 49 | url_create (&url, name); |
47 | 50 | ||
48 | /* 1st guest: if an ID is specify, shortcut */ | 51 | /* 1st guest: if an ID is specify, shortcut */ |
... | @@ -151,6 +154,14 @@ mailbox_scan (mailbox_t mbox, size_t msgno, size_t *pcount) | ... | @@ -151,6 +154,14 @@ mailbox_scan (mailbox_t mbox, size_t msgno, size_t *pcount) |
151 | return mbox->_scan (mbox, msgno, pcount); | 154 | return mbox->_scan (mbox, msgno, pcount); |
152 | } | 155 | } |
153 | 156 | ||
157 | int | ||
158 | mailbox_size (mailbox_t mbox, off_t *psize) | ||
159 | { | ||
160 | if (mbox == NULL || mbox->_size == NULL) | ||
161 | return 0; | ||
162 | return mbox->_size (mbox, psize); | ||
163 | } | ||
164 | |||
154 | /* locking */ | 165 | /* locking */ |
155 | int | 166 | int |
156 | mailbox_set_locker (mailbox_t mbox, locker_t locker) | 167 | mailbox_set_locker (mailbox_t mbox, locker_t locker) | ... | ... |
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
... | @@ -153,6 +153,17 @@ message_set_body (message_t msg, body_t body, void *owner) | ... | @@ -153,6 +153,17 @@ message_set_body (message_t msg, body_t body, void *owner) |
153 | } | 153 | } |
154 | 154 | ||
155 | int | 155 | int |
156 | message_set_stream (message_t msg, stream_t stream, void *owner) | ||
157 | { | ||
158 | if (msg == NULL) | ||
159 | return EINVAL; | ||
160 | if (msg->owner != owner) | ||
161 | return EACCES; | ||
162 | msg->stream = stream; | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | int | ||
156 | message_get_stream (message_t msg, stream_t *pstream) | 167 | message_get_stream (message_t msg, stream_t *pstream) |
157 | { | 168 | { |
158 | if (msg == NULL || pstream == NULL) | 169 | if (msg == NULL || pstream == NULL) |
... | @@ -177,11 +188,26 @@ message_get_stream (message_t msg, stream_t *pstream) | ... | @@ -177,11 +188,26 @@ message_get_stream (message_t msg, stream_t *pstream) |
177 | } | 188 | } |
178 | 189 | ||
179 | int | 190 | int |
191 | message_set_lines (message_t msg, int (*_lines) | ||
192 | (message_t, size_t *), void *owner) | ||
193 | { | ||
194 | if (msg == NULL) | ||
195 | return EINVAL; | ||
196 | if (msg->owner != owner) | ||
197 | return EACCES; | ||
198 | msg->_lines = _lines; | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | int | ||
180 | message_lines (message_t msg, size_t *plines) | 203 | message_lines (message_t msg, size_t *plines) |
181 | { | 204 | { |
182 | size_t hlines, blines; | 205 | size_t hlines, blines; |
183 | if (msg == NULL) | 206 | if (msg == NULL) |
184 | return EINVAL; | 207 | return EINVAL; |
208 | /* Overload */ | ||
209 | if (msg->_lines) | ||
210 | return msg->_lines (msg, plines); | ||
185 | if (plines) | 211 | if (plines) |
186 | { | 212 | { |
187 | hlines = blines = 0; | 213 | hlines = blines = 0; |
... | @@ -193,11 +219,26 @@ message_lines (message_t msg, size_t *plines) | ... | @@ -193,11 +219,26 @@ message_lines (message_t msg, size_t *plines) |
193 | } | 219 | } |
194 | 220 | ||
195 | int | 221 | int |
222 | message_set_size (message_t msg, int (*_size) | ||
223 | (message_t, size_t *), void *owner) | ||
224 | { | ||
225 | if (msg == NULL) | ||
226 | return EINVAL; | ||
227 | if (msg->owner != owner) | ||
228 | return EACCES; | ||
229 | msg->_size = _size; | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | int | ||
196 | message_size (message_t msg, size_t *psize) | 234 | message_size (message_t msg, size_t *psize) |
197 | { | 235 | { |
198 | size_t hsize, bsize; | 236 | size_t hsize, bsize; |
199 | if (msg == NULL) | 237 | if (msg == NULL) |
200 | return EINVAL; | 238 | return EINVAL; |
239 | /* Overload ? */ | ||
240 | if (msg->_size) | ||
241 | return msg->_size (msg, psize); | ||
201 | if (psize) | 242 | if (psize) |
202 | { | 243 | { |
203 | hsize = bsize = 0; | 244 | hsize = bsize = 0; |
... | @@ -235,14 +276,14 @@ message_from (message_t msg, char *buf, size_t len, size_t *pnwrite) | ... | @@ -235,14 +276,14 @@ message_from (message_t msg, char *buf, size_t len, size_t *pnwrite) |
235 | if (msg->_from) | 276 | if (msg->_from) |
236 | return msg->_from (msg, buf, len, pnwrite); | 277 | return msg->_from (msg, buf, len, pnwrite); |
237 | 278 | ||
238 | /* can it be extracted from the FROM: */ | 279 | /* can it be extracted from the From: */ |
239 | message_get_header (msg, &header); | 280 | message_get_header (msg, &header); |
240 | status = header_get_value (header, "FROM", NULL, 0, &n); | 281 | status = header_get_value (header, MU_HEADER_FROM, NULL, 0, &n); |
241 | if (status == 0 && n != 0) | 282 | if (status == 0 && n != 0) |
242 | { | 283 | { |
243 | char *from = calloc (1, n + 1); | 284 | char *from = calloc (1, n + 1); |
244 | char *addr; | 285 | char *addr; |
245 | header_get_value (header, "FROM", from, n + 1, NULL); | 286 | header_get_value (header, MU_HEADER_FROM, from, n + 1, NULL); |
246 | if (extract_addr (from, n, &addr, &n) == 0) | 287 | if (extract_addr (from, n, &addr, &n) == 0) |
247 | { | 288 | { |
248 | n = (n > len) ? len : n; | 289 | n = (n > len) ? len : n; |
... | @@ -258,6 +299,8 @@ message_from (message_t msg, char *buf, size_t len, size_t *pnwrite) | ... | @@ -258,6 +299,8 @@ message_from (message_t msg, char *buf, size_t len, size_t *pnwrite) |
258 | return 0; | 299 | return 0; |
259 | } | 300 | } |
260 | } | 301 | } |
302 | else if (status == EAGAIN) | ||
303 | return status; | ||
261 | 304 | ||
262 | /* oops */ | 305 | /* oops */ |
263 | n = (7 > len) ? len: 7; | 306 | n = (7 > len) ? len: 7; |
... | @@ -374,16 +417,43 @@ message_set_uidl (message_t msg, int (* _get_uidl) | ... | @@ -374,16 +417,43 @@ message_set_uidl (message_t msg, int (* _get_uidl) |
374 | } | 417 | } |
375 | 418 | ||
376 | int | 419 | int |
377 | message_is_mime (message_t msg) | 420 | message_set_is_multipart (message_t msg, int (*_is_multipart) |
421 | __P ((message_t, int *)), void *owner) | ||
422 | { | ||
423 | if (msg == NULL) | ||
424 | return EINVAL; | ||
425 | if (msg->owner != owner) | ||
426 | return EACCES; | ||
427 | msg->_is_multipart = _is_multipart; | ||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | int | ||
432 | message_is_multipart (message_t msg, int *p_is_mp) | ||
378 | { | 433 | { |
379 | header_t header; | 434 | header_t header; |
380 | int status; | 435 | int status; |
436 | size_t len = 0; | ||
381 | 437 | ||
382 | status = message_get_header(msg, &header); | 438 | if (msg == NULL || p_is_mp) |
383 | if (status != 0) | 439 | return EINVAL; |
384 | return status; | 440 | |
385 | status = header_get_value (header, "Mime-Version", NULL, 0, NULL); | 441 | message_get_header(msg, &header); |
386 | return (status == 0); | 442 | status = header_get_value (header, "Content-Type", NULL, 0, &len); |
443 | if (status == 0) | ||
444 | { | ||
445 | char *content_type = calloc (len + 1, sizeof (char)); | ||
446 | if (content_type == NULL) | ||
447 | return ENOMEM; | ||
448 | status = header_get_value (header, "Content-Type", content_type, | ||
449 | len, NULL); | ||
450 | *p_is_mp = strncasecmp ("multipart", content_type, | ||
451 | strlen ("multipart")) ? 0: 1; | ||
452 | free (content_type); | ||
453 | } | ||
454 | else | ||
455 | *p_is_mp = 0; | ||
456 | return status; | ||
387 | } | 457 | } |
388 | 458 | ||
389 | int | 459 | int |
... | @@ -422,6 +492,7 @@ message_get_part (message_t msg, size_t part, message_t *pmsg) | ... | @@ -422,6 +492,7 @@ message_get_part (message_t msg, size_t part, message_t *pmsg) |
422 | if (msg == NULL || pmsg == NULL) | 492 | if (msg == NULL || pmsg == NULL) |
423 | return EINVAL; | 493 | return EINVAL; |
424 | 494 | ||
495 | /* Overload. */ | ||
425 | if (msg->_get_part) | 496 | if (msg->_get_part) |
426 | return msg->_get_part (msg, part, pmsg); | 497 | return msg->_get_part (msg, part, pmsg); |
427 | 498 | ||
... | @@ -518,12 +589,11 @@ static int | ... | @@ -518,12 +589,11 @@ static int |
518 | message_read (stream_t is, char *buf, size_t buflen, | 589 | message_read (stream_t is, char *buf, size_t buflen, |
519 | off_t off, size_t *pnread ) | 590 | off_t off, size_t *pnread ) |
520 | { | 591 | { |
521 | message_t msg; | 592 | message_t msg = is->owner; |
522 | stream_t his, bis; | 593 | stream_t his, bis; |
523 | size_t hread, hsize, bread, bsize; | 594 | size_t hread, hsize, bread, bsize; |
524 | 595 | ||
525 | 596 | if (msg == NULL) | |
526 | if (is == NULL || (msg = is->owner) == NULL) | ||
527 | return EINVAL; | 597 | return EINVAL; |
528 | 598 | ||
529 | bsize = hsize = bread = hread = 0; | 599 | bsize = hsize = bread = hread = 0; |
... | @@ -536,16 +606,10 @@ message_read (stream_t is, char *buf, size_t buflen, | ... | @@ -536,16 +606,10 @@ message_read (stream_t is, char *buf, size_t buflen, |
536 | until you start reading them. So by checking hsize == bsize == 0, | 606 | until you start reading them. So by checking hsize == bsize == 0, |
537 | this kludge is a way of detecting the anomalie and start by the | 607 | this kludge is a way of detecting the anomalie and start by the |
538 | header. */ | 608 | header. */ |
539 | if ((size_t)off <= hsize || (hsize == 0 && bsize == 0)) | 609 | if ((size_t)off < hsize || (hsize == 0 && bsize == 0)) |
540 | { | 610 | { |
541 | header_get_stream (msg->header, &his); | 611 | header_get_stream (msg->header, &his); |
542 | stream_read (his, buf, buflen, off, &hread); | 612 | stream_read (his, buf, buflen, off, &hread); |
543 | /* still room left for some body, .. a pun ;-) */ | ||
544 | if ((buflen - hread) > 0) | ||
545 | { | ||
546 | body_get_stream (msg->body, &bis); | ||
547 | stream_read (bis, buf + hread, buflen - hread, 0, &bread); | ||
548 | } | ||
549 | } | 613 | } |
550 | else | 614 | else |
551 | { | 615 | { | ... | ... |
-
Please register or sign in to post a comment