Commit 4e0913bf 4e0913bf210cabf46e36866617158ef96ca90a91 by Alain Magloire

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

optionnal command, we fallback to RETR and ignore the body part.  This ugly
and wastefull and it made the code unnecessary complexe.  But fortunately
I do not know of any POP server that does not have TOP. It's a mess.
The other stuff was little cleanups.
1 parent 526e7396
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
......
1 2000--5-19 Sean 'Shaleh' Perry <shaleh@debian.org> 1 2000-09-01 Alain Magloire
2
3 *
4 2000-5-19 Sean 'Shaleh' Perry <shaleh@debian.org>
2 5
3 * libmailbox/mh.c: fleshed out mh_open() some more 6 * libmailbox/mh.c: fleshed out mh_open() some more
4 7
......
...@@ -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)
......
...@@ -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 {
......