For the new mailbox, one of the short coming with the old stream_t
object was that select() was not cover, meaning it was not possible to check if a stream was {read,write} ready. The old was to get the fd (stream_get_fd()) and do the select. Providing, stream_is_readready (stream_t, int timeout); stream_is_writeready (stream_t, int timeout); stream_is_exceptionpending (stream_t, int timeout); stream_is_open (stream_t); Takes care of it. It will work specially for tcp stream. * mailbox2/stream.c: New functions for the select calls: (stream_is_readready): New function. (stream_is_writeready): New function.(stream_t, int timeout); (stream_is_exceptionpending): New function. (stream_is_open): New function. * mailbox2/bstream.c (_bs_readline): Bug was truncating the string to early. (_bs_is_readready): New file. (_bs_is_writeready): New file. (_bs_is_exceptionpending): New file. (_bs_is_open): New file. * mailbox2/fstream.c: stubs for the select functions. * mailbox2/memstream.c: stubs for the select functions. * mailbox2/mapstream.c: stubs for the select functions. * mailbox2/tcpstream.c: stubs for the select functions. * mailbox2/include/mailutils/stream.h: Adjust the prototypes * mailbox2/include/mailutils/sys/stream.h: Adjust the prototypes It is better not to put threading (Pthread) code in the low level API. But instead in mailbox_t framework, where it can be control. * mailbox2/include/mailutils/pop3.h: Adjust the prototypes. * mailbox2/pop3/*.c: Remove threading code.
Showing
39 changed files
with
741 additions
and
1144 deletions
... | @@ -27,7 +27,7 @@ libmailbox_la_SOURCES = \ | ... | @@ -27,7 +27,7 @@ libmailbox_la_SOURCES = \ |
27 | md5-rsa.c \ | 27 | md5-rsa.c \ |
28 | memstream.c \ | 28 | memstream.c \ |
29 | message.c \ | 29 | message.c \ |
30 | mstream.c \ | 30 | mapstream.c \ |
31 | mutil.c \ | 31 | mutil.c \ |
32 | observable.c \ | 32 | observable.c \ |
33 | observer.c \ | 33 | observer.c \ | ... | ... |
... | @@ -268,9 +268,7 @@ _bs_readline (stream_t stream, char *buf, size_t count, size_t *pnread) | ... | @@ -268,9 +268,7 @@ _bs_readline (stream_t stream, char *buf, size_t count, size_t *pnread) |
268 | bs->rbuffer.ptr = nl; | 268 | bs->rbuffer.ptr = nl; |
269 | memcpy (s, p, len); | 269 | memcpy (s, p, len); |
270 | total += len; | 270 | total += len; |
271 | s[len] = '\0'; | 271 | s += len; |
272 | if (pnread) | ||
273 | *pnread = total; | ||
274 | break; | 272 | break; |
275 | } | 273 | } |
276 | bs->rbuffer.count -= len; | 274 | bs->rbuffer.count -= len; |
... | @@ -371,6 +369,38 @@ _bs_tell (stream_t stream, off_t *off) | ... | @@ -371,6 +369,38 @@ _bs_tell (stream_t stream, off_t *off) |
371 | return stream_tell (bs->stream, off); | 369 | return stream_tell (bs->stream, off); |
372 | } | 370 | } |
373 | 371 | ||
372 | static int | ||
373 | _bs_is_readready (stream_t stream, int timeout) | ||
374 | { | ||
375 | struct _bs *bs = (struct _bs *)stream; | ||
376 | /* Drain our buffer first. */ | ||
377 | if (bs->rbuffer.count > 0) | ||
378 | return 1; | ||
379 | return stream_is_readready (bs->stream, timeout); | ||
380 | } | ||
381 | |||
382 | static int | ||
383 | _bs_is_writeready (stream_t stream, int timeout) | ||
384 | { | ||
385 | struct _bs *bs = (struct _bs *)stream; | ||
386 | return stream_is_writeready (bs->stream, timeout); | ||
387 | } | ||
388 | |||
389 | static int | ||
390 | _bs_is_exceptionpending (stream_t stream, int timeout) | ||
391 | { | ||
392 | struct _bs *bs = (struct _bs *)stream; | ||
393 | return stream_is_exceptionpending (bs->stream, timeout); | ||
394 | } | ||
395 | |||
396 | static int | ||
397 | _bs_is_open (stream_t stream) | ||
398 | { | ||
399 | struct _bs *bs = (struct _bs *)stream; | ||
400 | return stream_is_open (bs->stream); | ||
401 | } | ||
402 | |||
403 | |||
374 | static struct _stream_vtable _bs_vtable = | 404 | static struct _stream_vtable _bs_vtable = |
375 | { | 405 | { |
376 | _bs_add_ref, | 406 | _bs_add_ref, |
... | @@ -394,6 +424,12 @@ static struct _stream_vtable _bs_vtable = | ... | @@ -394,6 +424,12 @@ static struct _stream_vtable _bs_vtable = |
394 | _bs_get_fd, | 424 | _bs_get_fd, |
395 | _bs_get_flags, | 425 | _bs_get_flags, |
396 | _bs_get_state, | 426 | _bs_get_state, |
427 | |||
428 | _bs_is_readready, | ||
429 | _bs_is_writeready, | ||
430 | _bs_is_exceptionpending, | ||
431 | |||
432 | _bs_is_open | ||
397 | }; | 433 | }; |
398 | 434 | ||
399 | int | 435 | int | ... | ... |
... | @@ -247,6 +247,36 @@ _fs_get_state (stream_t stream, enum stream_state *state) | ... | @@ -247,6 +247,36 @@ _fs_get_state (stream_t stream, enum stream_state *state) |
247 | } | 247 | } |
248 | 248 | ||
249 | static int | 249 | static int |
250 | _fs_is_open (stream_t stream) | ||
251 | { | ||
252 | struct _fs *fs = (struct _fs *)stream; | ||
253 | return (fs->file) ? 1 : 0; | ||
254 | } | ||
255 | |||
256 | static int | ||
257 | _fs_is_readready (stream_t stream, int timeout) | ||
258 | { | ||
259 | (void)timeout; | ||
260 | return _fs_is_open (stream); | ||
261 | } | ||
262 | |||
263 | static int | ||
264 | _fs_is_writeready (stream_t stream, int timeout) | ||
265 | { | ||
266 | (void)timeout; | ||
267 | return _fs_is_open (stream); | ||
268 | } | ||
269 | |||
270 | static int | ||
271 | _fs_is_exceptionpending (stream_t stream, int timeout) | ||
272 | { | ||
273 | (void)stream; | ||
274 | (void)timeout; | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | |||
279 | static int | ||
250 | _fs_close (stream_t stream) | 280 | _fs_close (stream_t stream) |
251 | { | 281 | { |
252 | struct _fs *fs = (struct _fs *)stream; | 282 | struct _fs *fs = (struct _fs *)stream; |
... | @@ -385,7 +415,13 @@ static struct _stream_vtable _fs_vtable = | ... | @@ -385,7 +415,13 @@ static struct _stream_vtable _fs_vtable = |
385 | 415 | ||
386 | _fs_get_fd, | 416 | _fs_get_fd, |
387 | _fs_get_flags, | 417 | _fs_get_flags, |
388 | _fs_get_state | 418 | _fs_get_state, |
419 | |||
420 | _fs_is_readready, | ||
421 | _fs_is_writeready, | ||
422 | _fs_is_exceptionpending, | ||
423 | |||
424 | _fs_is_open | ||
389 | }; | 425 | }; |
390 | 426 | ||
391 | int | 427 | int | ... | ... |
... | @@ -36,51 +36,49 @@ extern "C" { | ... | @@ -36,51 +36,49 @@ extern "C" { |
36 | struct _pop3; | 36 | struct _pop3; |
37 | typedef struct _pop3* pop3_t; | 37 | typedef struct _pop3* pop3_t; |
38 | 38 | ||
39 | struct pop3_list_item | 39 | extern int pop3_create __P ((pop3_t *)); |
40 | { | 40 | extern int pop3_destroy __P ((pop3_t)); |
41 | unsigned int msgno; | 41 | |
42 | unsigned int size; | 42 | extern int pop3_connect __P ((pop3_t, const char *, unsigned int)); |
43 | }; | 43 | extern int pop3_disconnect __P ((pop3_t)); |
44 | 44 | ||
45 | struct pop3_uidl_item | 45 | extern int pop3_set_carrier __P ((pop3_t, stream_t)); |
46 | { | 46 | extern int pop3_get_carrier __P ((pop3_t, stream_t *)); |
47 | unsigned int msgno; | 47 | |
48 | char *uidl; | 48 | extern int pop3_set_timeout __P ((pop3_t, int)); |
49 | }; | 49 | extern int pop3_get_timeout __P ((pop3_t, int *)); |
50 | 50 | ||
51 | extern int pop3_create __P ((pop3_t *)); | 51 | extern int pop3_apop __P ((pop3_t, const char *, const char *)); |
52 | extern void pop3_destroy __P ((pop3_t)); | 52 | |
53 | 53 | extern int pop3_capa __P ((pop3_t, iterator_t *)); | |
54 | extern int pop3_connect __P ((pop3_t, const char *, unsigned int)); | 54 | extern int pop3_capa_current __P ((iterator_t, char **)); |
55 | extern int pop3_disconnect __P ((pop3_t)); | 55 | |
56 | 56 | extern int pop3_dele __P ((pop3_t, unsigned int)); | |
57 | extern int pop3_set_stream __P ((pop3_t, stream_t)); | 57 | |
58 | extern int pop3_get_stream __P ((pop3_t, stream_t *)); | 58 | extern int pop3_list __P ((pop3_t, unsigned int, size_t *)); |
59 | 59 | extern int pop3_list_all __P ((pop3_t, iterator_t *)); | |
60 | extern int pop3_set_timeout __P ((pop3_t, unsigned int)); | 60 | extern int pop3_list_current __P ((iterator_t, unsigned int *, size_t *)); |
61 | extern int pop3_get_timeout __P ((pop3_t, unsigned int *)); | 61 | |
62 | 62 | extern int pop3_noop __P ((pop3_t)); | |
63 | extern int pop3_apop __P ((pop3_t, const char *, const char *)); | 63 | extern int pop3_pass __P ((pop3_t, const char *)); |
64 | extern int pop3_capa __P ((pop3_t, iterator_t *)); | 64 | extern int pop3_quit __P ((pop3_t)); |
65 | extern int pop3_dele __P ((pop3_t, unsigned int)); | 65 | extern int pop3_retr __P ((pop3_t, unsigned int, stream_t *)); |
66 | extern int pop3_list __P ((pop3_t, unsigned int, size_t *)); | 66 | extern int pop3_rset __P ((pop3_t)); |
67 | extern int pop3_list_all __P ((pop3_t, iterator_t *)); | 67 | extern int pop3_stat __P ((pop3_t, unsigned int *, size_t *)); |
68 | extern int pop3_noop __P ((pop3_t)); | 68 | extern int pop3_top __P ((pop3_t, unsigned int, |
69 | extern int pop3_pass __P ((pop3_t, const char *)); | 69 | unsigned int, stream_t *)); |
70 | extern int pop3_quit __P ((pop3_t)); | 70 | |
71 | extern int pop3_retr __P ((pop3_t, unsigned int, stream_t *)); | 71 | extern int pop3_uidl __P ((pop3_t, unsigned int, char **)); |
72 | extern int pop3_rset __P ((pop3_t)); | 72 | extern int pop3_uidl_all __P ((pop3_t, iterator_t *)); |
73 | extern int pop3_stat __P ((pop3_t, unsigned int *, size_t *)); | 73 | extern int pop3_uidl_current __P ((iterator_t, unsigned int *, char **)); |
74 | extern int pop3_top __P ((pop3_t, unsigned int, unsigned int, stream_t *)); | 74 | |
75 | extern int pop3_uidl __P ((pop3_t, unsigned int, char **)); | 75 | extern int pop3_user __P ((pop3_t, const char *)); |
76 | extern int pop3_uidl_all __P ((pop3_t, iterator_t *)); | 76 | |
77 | extern int pop3_user __P ((pop3_t, const char *)); | 77 | extern int pop3_readline __P ((pop3_t, char *, size_t, size_t *)); |
78 | 78 | extern int pop3_response __P ((pop3_t, char *, size_t, size_t *)); | |
79 | extern int pop3_readline __P ((pop3_t, char *, size_t, size_t *)); | 79 | extern int pop3_writeline __P ((pop3_t, const char *, ...)); |
80 | extern int pop3_response __P ((pop3_t, char *, size_t, size_t *)); | 80 | extern int pop3_sendline __P ((pop3_t, const char *)); |
81 | extern int pop3_writeline __P ((pop3_t, const char *, ...)); | 81 | extern int pop3_send __P ((pop3_t)); |
82 | extern int pop3_sendline __P ((pop3_t, const char *)); | ||
83 | extern int pop3_send __P ((pop3_t)); | ||
84 | 82 | ||
85 | #ifdef __cplusplus | 83 | #ifdef __cplusplus |
86 | } | 84 | } | ... | ... |
... | @@ -72,6 +72,12 @@ extern int stream_get_fd __P ((stream_t , int *)); | ... | @@ -72,6 +72,12 @@ extern int stream_get_fd __P ((stream_t , int *)); |
72 | extern int stream_get_flags __P ((stream_t, int *)); | 72 | extern int stream_get_flags __P ((stream_t, int *)); |
73 | extern int stream_get_state __P ((stream_t, enum stream_state *)); | 73 | extern int stream_get_state __P ((stream_t, enum stream_state *)); |
74 | 74 | ||
75 | extern int stream_is_readready __P ((stream_t, int)); | ||
76 | extern int stream_is_writeready __P ((stream_t, int)); | ||
77 | extern int stream_is_exceptionpending __P ((stream_t, int)); | ||
78 | |||
79 | extern int stream_is_open __P ((stream_t)); | ||
80 | |||
75 | /* Misc. */ | 81 | /* Misc. */ |
76 | extern int stream_file_create __P ((stream_t *)); | 82 | extern int stream_file_create __P ((stream_t *)); |
77 | extern int stream_mapfile_create __P ((stream_t *)); | 83 | extern int stream_mapfile_create __P ((stream_t *)); | ... | ... |
... | @@ -23,8 +23,8 @@ | ... | @@ -23,8 +23,8 @@ |
23 | #include <mailutils/pop3.h> | 23 | #include <mailutils/pop3.h> |
24 | #include <mailutils/sys/stream.h> | 24 | #include <mailutils/sys/stream.h> |
25 | #include <mailutils/sys/iterator.h> | 25 | #include <mailutils/sys/iterator.h> |
26 | #include <mailutils/monitor.h> | ||
27 | #include <mailutils/error.h> | 26 | #include <mailutils/error.h> |
27 | #include <mailutils/monitor.h> | ||
28 | 28 | ||
29 | #ifdef DMALLOC | 29 | #ifdef DMALLOC |
30 | # include <dmalloc.h> | 30 | # include <dmalloc.h> |
... | @@ -61,7 +61,7 @@ struct p_iterator | ... | @@ -61,7 +61,7 @@ struct p_iterator |
61 | pop3_t pop3; | 61 | pop3_t pop3; |
62 | unsigned int ref; | 62 | unsigned int ref; |
63 | int done; | 63 | int done; |
64 | void *item; | 64 | char *item; |
65 | monitor_t lock; | 65 | monitor_t lock; |
66 | }; | 66 | }; |
67 | 67 | ||
... | @@ -103,13 +103,11 @@ struct _pop3 | ... | @@ -103,13 +103,11 @@ struct _pop3 |
103 | unsigned timeout; /* Default is 10 minutes. */ | 103 | unsigned timeout; /* Default is 10 minutes. */ |
104 | 104 | ||
105 | enum pop3_state state; | 105 | enum pop3_state state; |
106 | stream_t stream; /* TCP Connection. */ | 106 | stream_t carrier; /* TCP Connection. */ |
107 | monitor_t lock; | ||
108 | }; | 107 | }; |
109 | 108 | ||
110 | extern int pop3_iterator_create __P ((pop3_t, iterator_t *)); | 109 | extern int pop3_iterator_create __P ((pop3_t, iterator_t *)); |
111 | extern int pop3_stream_create __P ((pop3_t, stream_t *)); | 110 | extern int pop3_stream_create __P ((pop3_t, stream_t *)); |
112 | extern void pop3_cleanup __P ((void *)); | ||
113 | 111 | ||
114 | /* Check for non recoverable error. */ | 112 | /* Check for non recoverable error. */ |
115 | #define POP3_CHECK_EAGAIN(pop3, status) \ | 113 | #define POP3_CHECK_EAGAIN(pop3, status) \ | ... | ... |
... | @@ -47,6 +47,12 @@ struct _stream_vtable | ... | @@ -47,6 +47,12 @@ struct _stream_vtable |
47 | int (*get_fd) __P ((stream_t , int *)); | 47 | int (*get_fd) __P ((stream_t , int *)); |
48 | int (*get_flags) __P ((stream_t, int *)); | 48 | int (*get_flags) __P ((stream_t, int *)); |
49 | int (*get_state) __P ((stream_t, enum stream_state *)); | 49 | int (*get_state) __P ((stream_t, enum stream_state *)); |
50 | |||
51 | int (*is_readready) __P ((stream_t, int)); | ||
52 | int (*is_writeready) __P ((stream_t, int)); | ||
53 | int (*is_exceptionpending) __P ((stream_t, int)); | ||
54 | |||
55 | int (*is_open) __P ((stream_t)); | ||
50 | }; | 56 | }; |
51 | 57 | ||
52 | struct _stream | 58 | struct _stream | ... | ... |
... | @@ -238,6 +238,38 @@ _memory_tell (stream_t stream, off_t *off) | ... | @@ -238,6 +238,38 @@ _memory_tell (stream_t stream, off_t *off) |
238 | } | 238 | } |
239 | 239 | ||
240 | static int | 240 | static int |
241 | _memory_is_open (stream_t stream) | ||
242 | { | ||
243 | (void)stream; | ||
244 | return 1; | ||
245 | } | ||
246 | |||
247 | static int | ||
248 | _memory_is_readready (stream_t stream, int timeout) | ||
249 | { | ||
250 | (void)stream; | ||
251 | (void)timeout; | ||
252 | return 1; | ||
253 | } | ||
254 | |||
255 | static int | ||
256 | _memory_is_writeready (stream_t stream, int timeout) | ||
257 | { | ||
258 | (void)stream; | ||
259 | (void)timeout; | ||
260 | return 1; | ||
261 | } | ||
262 | |||
263 | static int | ||
264 | _memory_is_exceptionpending (stream_t stream, int timeout) | ||
265 | { | ||
266 | (void)stream; | ||
267 | (void)timeout; | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | |||
272 | static int | ||
241 | _memory_open (stream_t stream, const char *filename, int port, int flags) | 273 | _memory_open (stream_t stream, const char *filename, int port, int flags) |
242 | { | 274 | { |
243 | struct _memory_stream *mem = (struct _memory_stream *)stream; | 275 | struct _memory_stream *mem = (struct _memory_stream *)stream; |
... | @@ -278,7 +310,13 @@ static struct _stream_vtable _mem_vtable = | ... | @@ -278,7 +310,13 @@ static struct _stream_vtable _mem_vtable = |
278 | 310 | ||
279 | _memory_get_fd, | 311 | _memory_get_fd, |
280 | _memory_get_flags, | 312 | _memory_get_flags, |
281 | _memory_get_state | 313 | _memory_get_state, |
314 | |||
315 | _memory_is_readready, | ||
316 | _memory_is_writeready, | ||
317 | _memory_is_exceptionpending, | ||
318 | |||
319 | _memory_is_open | ||
282 | }; | 320 | }; |
283 | 321 | ||
284 | int | 322 | int | ... | ... |
mailbox2/mstream.c
deleted
100644 → 0
1 | /* GNU mailutils - a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001 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 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | |||
22 | #include <errno.h> | ||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <string.h> | ||
26 | |||
27 | #include <sys/types.h> | ||
28 | #include <sys/stat.h> | ||
29 | #include <fcntl.h> | ||
30 | #include <unistd.h> | ||
31 | |||
32 | #include <mailutils/sys/mstream.h> | ||
33 | #include <mailutils/error.h> | ||
34 | |||
35 | #ifdef _POSIX_MAPPED_FILES | ||
36 | #include <sys/mman.h> | ||
37 | |||
38 | #ifndef MAP_FAILED | ||
39 | # define MAP_FAILED (void*)-1 | ||
40 | #endif | ||
41 | |||
42 | static int | ||
43 | _ms_add_ref (stream_t stream) | ||
44 | { | ||
45 | int status; | ||
46 | struct _ms *ms = (struct _ms *)stream; | ||
47 | monitor_lock (ms->lock); | ||
48 | status = ++ms->ref; | ||
49 | monitor_unlock (ms->lock); | ||
50 | return status; | ||
51 | } | ||
52 | |||
53 | static int | ||
54 | _ms_destroy (stream_t stream) | ||
55 | { | ||
56 | struct _ms *ms = (struct _ms *)stream; | ||
57 | |||
58 | if (ms->ptr != MAP_FAILED) | ||
59 | { | ||
60 | if (ms->ptr) | ||
61 | munmap (ms->ptr, ms->size); | ||
62 | if (ms->fd != -1) | ||
63 | close (ms->fd); | ||
64 | monitor_destroy (ms->lock); | ||
65 | } | ||
66 | free (ms); | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int | ||
71 | _ms_release (stream_t stream) | ||
72 | { | ||
73 | int status; | ||
74 | struct _ms *ms = (struct _ms *)stream; | ||
75 | monitor_lock (ms->lock); | ||
76 | status = --ms->ref; | ||
77 | if (status <= 0) | ||
78 | { | ||
79 | monitor_unlock (ms->lock); | ||
80 | _ms_destroy (stream); | ||
81 | return 0; | ||
82 | } | ||
83 | monitor_unlock (ms->lock); | ||
84 | return status; | ||
85 | } | ||
86 | |||
87 | static int | ||
88 | _ms_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) | ||
89 | { | ||
90 | struct _ms *ms = (struct _ms *)stream; | ||
91 | size_t n = 0; | ||
92 | |||
93 | monitor_lock (ms->lock); | ||
94 | if (ms->ptr != MAP_FAILED && ms->ptr) | ||
95 | { | ||
96 | if (ms->offset < (off_t)ms->size) | ||
97 | { | ||
98 | n = ((ms->offset + osize) > ms->size) ? | ||
99 | ms->size - ms->offset : osize; | ||
100 | memcpy (optr, ms->ptr + ms->offset, n); | ||
101 | ms->offset += n; | ||
102 | } | ||
103 | } | ||
104 | monitor_unlock (ms->lock); | ||
105 | |||
106 | if (nbytes) | ||
107 | *nbytes = n; | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static int | ||
112 | _ms_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes) | ||
113 | { | ||
114 | struct _ms *ms = (struct _ms *)stream; | ||
115 | size_t n = 0; | ||
116 | |||
117 | monitor_lock (ms->lock); | ||
118 | if (ms->ptr != MAP_FAILED && ms->ptr) | ||
119 | { | ||
120 | if (ms->offset < (off_t)ms->size) | ||
121 | { | ||
122 | /* Save space for the null byte. */ | ||
123 | char *nl; | ||
124 | osize--; | ||
125 | nl = memchr (ms->ptr + ms->offset, '\n', ms->size - ms->offset); | ||
126 | n = (nl) ? nl - (ms->ptr + ms->offset) + 1 : ms->size - ms->offset; | ||
127 | n = (n > osize) ? osize : n; | ||
128 | memcpy (optr, ms->ptr + ms->offset, n); | ||
129 | optr[n] = '\0'; | ||
130 | ms->offset += n; | ||
131 | } | ||
132 | } | ||
133 | monitor_unlock (ms->lock); | ||
134 | |||
135 | if (nbytes) | ||
136 | *nbytes = n; | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static int | ||
141 | _ms_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes) | ||
142 | { | ||
143 | struct _ms *ms = (struct _ms *)stream; | ||
144 | int err = 0; | ||
145 | size_t n = 0; | ||
146 | |||
147 | monitor_lock (ms->lock); | ||
148 | if (ms->mflags & PROT_WRITE) | ||
149 | { | ||
150 | /* Bigger we have to remmap. */ | ||
151 | if (ms->size < (ms->offset + isize)) | ||
152 | { | ||
153 | if (ms->ptr != MAP_FAILED && munmap (ms->ptr, ms->size) == 0) | ||
154 | { | ||
155 | ms->ptr = MAP_FAILED; | ||
156 | if (ftruncate (ms->fd, ms->offset + isize) == 0) | ||
157 | { | ||
158 | ms->ptr = mmap (0, ms->offset + isize, ms->mflags, | ||
159 | MAP_SHARED, ms->fd, 0); | ||
160 | if (ms->ptr != MAP_FAILED) | ||
161 | ms->size = ms->offset + isize; | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | |||
166 | if (ms->ptr != MAP_FAILED) | ||
167 | { | ||
168 | if (isize > 0) | ||
169 | memcpy (ms->ptr + ms->offset, iptr, isize); | ||
170 | ms->offset += isize; | ||
171 | n = isize; | ||
172 | } | ||
173 | else | ||
174 | err = MU_ERROR_IO; | ||
175 | } | ||
176 | else | ||
177 | err = MU_ERROR_IO; | ||
178 | monitor_unlock (ms->lock); | ||
179 | |||
180 | if (nbytes) | ||
181 | *nbytes = n; | ||
182 | return err; | ||
183 | } | ||
184 | |||
185 | static int | ||
186 | _ms_truncate (stream_t stream, off_t len) | ||
187 | { | ||
188 | struct _ms *ms = (struct _ms *)stream; | ||
189 | int err = 0; | ||
190 | |||
191 | monitor_lock (ms->lock); | ||
192 | if (ms->ptr != MAP_FAILED) | ||
193 | { | ||
194 | /* Remap. */ | ||
195 | if (ms->ptr && munmap (ms->ptr, ms->size) == 0) | ||
196 | { | ||
197 | if (ftruncate (ms->fd, len) == 0) | ||
198 | { | ||
199 | ms->ptr = (len) ? | ||
200 | mmap (0, len, ms->mflags, MAP_SHARED, ms->fd, 0) : NULL; | ||
201 | if (ms->ptr != MAP_FAILED) | ||
202 | { | ||
203 | ms->size = len; | ||
204 | } | ||
205 | else | ||
206 | err = errno; | ||
207 | } | ||
208 | else | ||
209 | err = errno; | ||
210 | } | ||
211 | } | ||
212 | monitor_unlock (ms->lock); | ||
213 | return err; | ||
214 | } | ||
215 | |||
216 | static int | ||
217 | _ms_get_size (stream_t stream, off_t *psize) | ||
218 | { | ||
219 | struct _ms *ms = (struct _ms *)stream; | ||
220 | struct stat stbuf; | ||
221 | int err = 0; | ||
222 | |||
223 | monitor_lock (ms->lock); | ||
224 | stbuf.st_size = 0; | ||
225 | if (ms->ptr != MAP_FAILED) | ||
226 | { | ||
227 | if (ms->ptr) | ||
228 | msync (ms->ptr, ms->size, MS_SYNC); | ||
229 | |||
230 | if (fstat(ms->fd, &stbuf) == 0) | ||
231 | { | ||
232 | /* Remap. */ | ||
233 | if (ms->size != (size_t)stbuf.st_size) | ||
234 | { | ||
235 | if (ms->ptr && munmap (ms->ptr, ms->size) == 0) | ||
236 | { | ||
237 | if (ms->size) | ||
238 | { | ||
239 | ms->ptr = mmap (0, ms->size, ms->mflags , MAP_SHARED, | ||
240 | ms->fd, 0); | ||
241 | if (ms->ptr != MAP_FAILED) | ||
242 | ms->size = stbuf.st_size; | ||
243 | else | ||
244 | err = errno; | ||
245 | } | ||
246 | else | ||
247 | ms->ptr = NULL; | ||
248 | } | ||
249 | else | ||
250 | err = errno; | ||
251 | } | ||
252 | } | ||
253 | } | ||
254 | monitor_unlock (ms->lock); | ||
255 | if (psize) | ||
256 | *psize = stbuf.st_size; | ||
257 | return err; | ||
258 | } | ||
259 | |||
260 | static int | ||
261 | _ms_flush (stream_t stream) | ||
262 | { | ||
263 | int err = 0; | ||
264 | struct _ms *ms = (struct _ms *)stream; | ||
265 | monitor_lock (ms->lock); | ||
266 | if (ms->ptr != MAP_FAILED && ms->ptr != NULL) | ||
267 | err = msync (ms->ptr, ms->size, MS_SYNC); | ||
268 | monitor_unlock (ms->lock); | ||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static int | ||
273 | _ms_get_fd (stream_t stream, int *pfd) | ||
274 | { | ||
275 | struct _ms *ms = (struct _ms *)stream; | ||
276 | if (pfd) | ||
277 | *pfd = ms->fd; | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int | ||
282 | _ms_get_flags (stream_t stream, int *flags) | ||
283 | { | ||
284 | struct _ms *ms = (struct _ms *)stream; | ||
285 | if (flags == NULL) | ||
286 | return MU_ERROR_INVALID_PARAMETER; | ||
287 | *flags = ms->flags; | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int | ||
292 | _ms_get_state (stream_t stream, enum stream_state *state) | ||
293 | { | ||
294 | (void)stream; | ||
295 | if (state == NULL) | ||
296 | return MU_ERROR_INVALID_PARAMETER; | ||
297 | *state = MU_STREAM_NO_STATE; | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static int | ||
302 | _ms_seek (stream_t stream, off_t off, enum stream_whence whence) | ||
303 | { | ||
304 | struct _ms *ms = (struct _ms *)stream; | ||
305 | off_t noff = ms->offset; | ||
306 | int err = 0; | ||
307 | if (whence == MU_STREAM_WHENCE_SET) | ||
308 | noff = off; | ||
309 | else if (whence == MU_STREAM_WHENCE_CUR) | ||
310 | noff += off; | ||
311 | else if (whence == MU_STREAM_WHENCE_END) | ||
312 | noff = ms->size + off; | ||
313 | else | ||
314 | noff = -1; /* error. */ | ||
315 | if (noff >= 0) | ||
316 | { | ||
317 | if (noff > ms->offset) | ||
318 | _ms_truncate (stream, noff); | ||
319 | ms->offset = noff; | ||
320 | } | ||
321 | else | ||
322 | err = MU_ERROR_INVALID_PARAMETER; | ||
323 | return err; | ||
324 | } | ||
325 | |||
326 | static int | ||
327 | _ms_tell (stream_t stream, off_t *off) | ||
328 | { | ||
329 | struct _ms *ms = (struct _ms *)stream; | ||
330 | if (off == NULL) | ||
331 | return MU_ERROR_INVALID_PARAMETER; | ||
332 | *off = ms->offset; | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static int | ||
337 | _ms_close (stream_t stream) | ||
338 | { | ||
339 | struct _ms *ms = (struct _ms *)stream; | ||
340 | int err = 0; | ||
341 | monitor_lock (ms->lock); | ||
342 | if (ms->ptr != MAP_FAILED) | ||
343 | { | ||
344 | if (ms->ptr && munmap (ms->ptr, ms->size) != 0) | ||
345 | err = errno; | ||
346 | ms->ptr = MAP_FAILED; | ||
347 | } | ||
348 | if (ms->fd != -1) | ||
349 | if (close (ms->fd) != 0) | ||
350 | err = errno; | ||
351 | ms->fd = -1; | ||
352 | monitor_unlock (ms->lock); | ||
353 | return err; | ||
354 | } | ||
355 | |||
356 | static int | ||
357 | _ms_open (stream_t stream, const char *filename, int port, int flags) | ||
358 | { | ||
359 | struct _ms *ms = (struct _ms *)stream; | ||
360 | int mflag, flg; | ||
361 | struct stat st; | ||
362 | |||
363 | (void)port; /* Ignored. */ | ||
364 | |||
365 | /* Close any previous file. */ | ||
366 | if (ms->ptr != MAP_FAILED) | ||
367 | { | ||
368 | if (ms->ptr) | ||
369 | munmap (ms->ptr, ms->size); | ||
370 | ms->ptr = MAP_FAILED; | ||
371 | } | ||
372 | if (ms->fd != -1) | ||
373 | { | ||
374 | close (ms->fd); | ||
375 | ms->fd = -1; | ||
376 | } | ||
377 | /* Map the flags to the system equivalent */ | ||
378 | if ((flags & MU_STREAM_WRITE) && (flags & MU_STREAM_READ)) | ||
379 | return EINVAL; | ||
380 | else if (flags & MU_STREAM_WRITE) | ||
381 | { | ||
382 | mflag = PROT_WRITE; | ||
383 | flg = O_WRONLY; | ||
384 | } | ||
385 | else if (flags & MU_STREAM_RDWR) | ||
386 | { | ||
387 | mflag = PROT_READ | PROT_WRITE; | ||
388 | flg = O_RDWR; | ||
389 | } | ||
390 | else if (flags & MU_STREAM_CREAT) | ||
391 | return ENOSYS; | ||
392 | else /* default */ | ||
393 | { | ||
394 | mflag = PROT_READ; | ||
395 | flg = O_RDONLY; | ||
396 | } | ||
397 | |||
398 | ms->fd = open (filename, flg); | ||
399 | if (ms->fd < 0) | ||
400 | return errno; | ||
401 | if (fstat (ms->fd, &st) != 0) | ||
402 | { | ||
403 | int err = errno; | ||
404 | close (ms->fd); | ||
405 | return err; | ||
406 | } | ||
407 | ms->size = st.st_size; | ||
408 | if (ms->size) | ||
409 | { | ||
410 | ms->ptr = mmap (0, ms->size, mflag , MAP_SHARED, ms->fd, 0); | ||
411 | if (ms->ptr == MAP_FAILED) | ||
412 | { | ||
413 | int err = errno; | ||
414 | close (ms->fd); | ||
415 | ms->ptr = MAP_FAILED; | ||
416 | return err; | ||
417 | } | ||
418 | } | ||
419 | else | ||
420 | ms->ptr = NULL; | ||
421 | ms->mflags = mflag; | ||
422 | ms->flags = flags; | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static struct _stream_vtable _ms_vtable = | ||
427 | { | ||
428 | _ms_add_ref, | ||
429 | _ms_release, | ||
430 | _ms_destroy, | ||
431 | |||
432 | _ms_open, | ||
433 | _ms_close, | ||
434 | |||
435 | _ms_read, | ||
436 | _ms_readline, | ||
437 | _ms_write, | ||
438 | |||
439 | _ms_seek, | ||
440 | _ms_tell, | ||
441 | |||
442 | _ms_get_size, | ||
443 | _ms_truncate, | ||
444 | _ms_flush, | ||
445 | |||
446 | _ms_get_fd, | ||
447 | _ms_get_flags, | ||
448 | _ms_get_state, | ||
449 | }; | ||
450 | |||
451 | #endif /* _POSIX_MAPPED_FILES */ | ||
452 | |||
453 | int | ||
454 | stream_mapfile_create (stream_t *pstream) | ||
455 | { | ||
456 | #ifndef _POSIX_MAPPED_FILES | ||
457 | return ENOSYS; | ||
458 | #else | ||
459 | struct _ms *ms; | ||
460 | |||
461 | if (pstream == NULL) | ||
462 | return MU_ERROR_INVALID_PARAMETER; | ||
463 | |||
464 | ms = calloc (1, sizeof *ms); | ||
465 | if (ms == NULL) | ||
466 | return MU_ERROR_NO_MEMORY; | ||
467 | |||
468 | ms->base.vtable = &_ms_vtable; | ||
469 | ms->ref = 1; | ||
470 | ms->fd = -1; | ||
471 | ms->offset = -1; | ||
472 | ms->flags = 0; | ||
473 | ms->mflags = 0; | ||
474 | monitor_create (&(ms->lock)); | ||
475 | *pstream = &ms->base; | ||
476 | |||
477 | return 0; | ||
478 | #endif /* _POSIX_MAPPED_FILES */ | ||
479 | } |
... | @@ -25,20 +25,19 @@ | ... | @@ -25,20 +25,19 @@ |
25 | #ifdef HAVE_STRINGS_H | 25 | #ifdef HAVE_STRINGS_H |
26 | #include <strings.h> | 26 | #include <strings.h> |
27 | #endif | 27 | #endif |
28 | #include <string.h> | ||
29 | #include <time.h> | 28 | #include <time.h> |
30 | #include <pwd.h> | 29 | #include <pwd.h> |
31 | #include <unistd.h> | 30 | #include <unistd.h> |
31 | #include <string.h> | ||
32 | 32 | ||
33 | #include <mailutils/mutil.h> | 33 | #include <mailutils/mutil.h> |
34 | 34 | #include <mailutils/list.h> | |
35 | #ifdef HAVE_MYSQL | 35 | #include <mailutils/iterator.h> |
36 | #include "../MySql/MySql.h" | ||
37 | #endif | ||
38 | 36 | ||
39 | /* convert a sequence of hex characters into an integer */ | 37 | /* convert a sequence of hex characters into an integer */ |
40 | 38 | ||
41 | unsigned long mu_hex2ul(char hex) | 39 | unsigned long |
40 | mu_hex2ul (char hex) | ||
42 | { | 41 | { |
43 | if (hex >= '0' && hex <= '9') | 42 | if (hex >= '0' && hex <= '9') |
44 | return hex - '0'; | 43 | return hex - '0'; |
... | @@ -52,21 +51,22 @@ unsigned long mu_hex2ul(char hex) | ... | @@ -52,21 +51,22 @@ unsigned long mu_hex2ul(char hex) |
52 | return -1; | 51 | return -1; |
53 | } | 52 | } |
54 | 53 | ||
55 | size_t mu_hexstr2ul(unsigned long* ul, const char* hex, size_t len) | 54 | size_t |
55 | mu_hexstr2ul (unsigned long *ul, const char *hex, size_t len) | ||
56 | { | 56 | { |
57 | size_t r; | 57 | size_t r; |
58 | 58 | ||
59 | *ul = 0; | 59 | *ul = 0; |
60 | 60 | ||
61 | for (r = 0; r < len; r++) | 61 | for (r = 0; r < len; r++) |
62 | { | 62 | { |
63 | unsigned long v = mu_hex2ul(hex[r]); | 63 | unsigned long v = mu_hex2ul (hex[r]); |
64 | 64 | ||
65 | if (v == (unsigned long)-1) | 65 | if (v == (unsigned long)-1) |
66 | return r; | 66 | return r; |
67 | 67 | ||
68 | *ul = *ul * 16 + v; | 68 | *ul = *ul * 16 + v; |
69 | } | 69 | } |
70 | return r; | 70 | return r; |
71 | } | 71 | } |
72 | 72 | ||
... | @@ -86,18 +86,18 @@ mu_tm2time (struct tm *timeptr, mu_timezone* tz) | ... | @@ -86,18 +86,18 @@ mu_tm2time (struct tm *timeptr, mu_timezone* tz) |
86 | { | 86 | { |
87 | int offset = tz ? tz->utc_offset : 0; | 87 | int offset = tz ? tz->utc_offset : 0; |
88 | 88 | ||
89 | return mktime(timeptr) + mu_utc_offset() - offset; | 89 | return mktime (timeptr) + mu_utc_offset () - offset; |
90 | } | 90 | } |
91 | 91 | ||
92 | /* Convert time 0 at UTC to our localtime, that tells us the offset | 92 | /* Convert time 0 at UTC to our localtime, that tells us the offset |
93 | of our current timezone from UTC. */ | 93 | of our current timezone from UTC. */ |
94 | time_t | 94 | time_t |
95 | mu_utc_offset(void) | 95 | mu_utc_offset (void) |
96 | { | 96 | { |
97 | time_t t = 0; | 97 | time_t t = 0; |
98 | struct tm* tm = gmtime(&t); | 98 | struct tm* tm = gmtime (&t); |
99 | 99 | ||
100 | return - mktime(tm); | 100 | return - mktime (tm); |
101 | } | 101 | } |
102 | 102 | ||
103 | static const char *months[] = | 103 | static const char *months[] = |
... | @@ -246,7 +246,6 @@ mu_parse_ctime_date_time (const char **p, struct tm *tm, mu_timezone * tz) | ... | @@ -246,7 +246,6 @@ mu_parse_ctime_date_time (const char **p, struct tm *tm, mu_timezone * tz) |
246 | return 0; | 246 | return 0; |
247 | } | 247 | } |
248 | 248 | ||
249 | |||
250 | char * | 249 | char * |
251 | mu_get_homedir (void) | 250 | mu_get_homedir (void) |
252 | { | 251 | { |
... | @@ -255,7 +254,7 @@ mu_get_homedir (void) | ... | @@ -255,7 +254,7 @@ mu_get_homedir (void) |
255 | { | 254 | { |
256 | struct passwd *pwd; | 255 | struct passwd *pwd; |
257 | 256 | ||
258 | pwd = getpwuid(getuid()); | 257 | pwd = getpwuid (getuid ()); |
259 | if (!pwd) | 258 | if (!pwd) |
260 | return NULL; | 259 | return NULL; |
261 | homedir = pwd->pw_dir; | 260 | homedir = pwd->pw_dir; |
... | @@ -298,11 +297,7 @@ mu_tilde_expansion (const char *ref, const char *delim, const char *homedir) | ... | @@ -298,11 +297,7 @@ mu_tilde_expansion (const char *ref, const char *delim, const char *homedir) |
298 | name = calloc (s - p + 1, 1); | 297 | name = calloc (s - p + 1, 1); |
299 | memcpy (name, p, s - p); | 298 | memcpy (name, p, s - p); |
300 | name [s - p] = '\0'; | 299 | name [s - p] = '\0'; |
301 | pw = getpwnam (name); | 300 | pw = mu_getpwnam (name); |
302 | #ifdef HAVE_MYSQL | ||
303 | if (!pw) | ||
304 | pw = getMpwnam(name); | ||
305 | #endif /* HAVE_MYSQL */ | ||
306 | free (name); | 301 | free (name); |
307 | if (pw) | 302 | if (pw) |
308 | { | 303 | { |
... | @@ -333,3 +328,80 @@ util_cpystr (char *dst, const char *src, size_t size) | ... | @@ -333,3 +328,80 @@ util_cpystr (char *dst, const char *src, size_t size) |
333 | dst[len] = '\0'; | 328 | dst[len] = '\0'; |
334 | return len; | 329 | return len; |
335 | } | 330 | } |
331 | |||
332 | static list_t _app_getpwnam = NULL; | ||
333 | |||
334 | void | ||
335 | mu_register_getpwnam (struct passwd *(*fun) __P((const char *))) | ||
336 | { | ||
337 | if (!_app_getpwnam && list_create (&_app_getpwnam)) | ||
338 | return; | ||
339 | list_append (_app_getpwnam, fun); | ||
340 | } | ||
341 | |||
342 | struct passwd * | ||
343 | mu_getpwnam (const char *name) | ||
344 | { | ||
345 | struct passwd *p; | ||
346 | iterator_t itr; | ||
347 | |||
348 | p = getpwnam (name); | ||
349 | |||
350 | if (!p && iterator_create (&itr, _app_getpwnam) == 0) | ||
351 | { | ||
352 | struct passwd *(*fun) __P((const char *)); | ||
353 | for (iterator_first (itr); !p && !iterator_is_done (itr); | ||
354 | iterator_next (itr)) | ||
355 | { | ||
356 | iterator_current (itr, (void **)&fun); | ||
357 | p = (*fun) (name); | ||
358 | } | ||
359 | |||
360 | iterator_destroy (&itr); | ||
361 | } | ||
362 | return p; | ||
363 | } | ||
364 | |||
365 | int mu_virtual_domain; | ||
366 | |||
367 | #ifdef USE_VIRTUAL_DOMAINS | ||
368 | |||
369 | struct passwd * | ||
370 | getpwnam_virtual (const char *u) | ||
371 | { | ||
372 | struct passwd *pw = NULL; | ||
373 | FILE *pfile; | ||
374 | size_t i = 0, len = strlen (u), delim = 0; | ||
375 | char *filename; | ||
376 | |||
377 | mu_virtual_domain = 0; | ||
378 | for (i = 0; i < len && delim == 0; i++) | ||
379 | if (u[i] == '!' || u[i] == ':' || u[i] == '@') | ||
380 | delim = i; | ||
381 | |||
382 | if (delim == 0) | ||
383 | return NULL; | ||
384 | |||
385 | filename = malloc (strlen (SITE_VIRTUAL_PWDDIR) + | ||
386 | strlen (&u[delim + 1]) + 2 /* slash and null byte */); | ||
387 | if (filename == NULL) | ||
388 | return NULL; | ||
389 | |||
390 | sprintf (filename, "%s/%s", SITE_VIRTUAL_PWDDIR, &u[delim + 1]); | ||
391 | pfile = fopen (filename, "r"); | ||
392 | free (filename); | ||
393 | |||
394 | if (pfile) | ||
395 | while ((pw = fgetpwent (pfile)) != NULL) | ||
396 | { | ||
397 | if (strlen (pw->pw_name) == delim && !strncmp (u, pw->pw_name, delim)) | ||
398 | { | ||
399 | mu_virtual_domain = 1; | ||
400 | break; | ||
401 | } | ||
402 | } | ||
403 | |||
404 | return pw; | ||
405 | } | ||
406 | |||
407 | #endif | ... | ... |
... | @@ -10,6 +10,7 @@ lib_LTLIBRARIES = libpop3.la | ... | @@ -10,6 +10,7 @@ lib_LTLIBRARIES = libpop3.la |
10 | libmailbox_la_SOURCES = \ | 10 | libmailbox_la_SOURCES = \ |
11 | pop3_apop.c \ | 11 | pop3_apop.c \ |
12 | pop3_capa.c \ | 12 | pop3_capa.c \ |
13 | pop3_carrier.c \ | ||
13 | pop3_cleanup.c \ | 14 | pop3_cleanup.c \ |
14 | pop3_connect.c \ | 15 | pop3_connect.c \ |
15 | pop3_create.c \ | 16 | pop3_create.c \ | ... | ... |
... | @@ -29,12 +29,16 @@ | ... | @@ -29,12 +29,16 @@ |
29 | APOP name digest | 29 | APOP name digest |
30 | a string identifying a mailbox and a MD5 digest string (both required) | 30 | a string identifying a mailbox and a MD5 digest string (both required) |
31 | */ | 31 | */ |
32 | static int | 32 | int |
33 | pop3_apop0 (pop3_t pop3, const char *user, const char *secret) | 33 | pop3_apop (pop3_t pop3, const char *user, const char *secret) |
34 | { | 34 | { |
35 | int status; | 35 | int status; |
36 | 36 | ||
37 | /* The server did not offer a time stamp in the greeting, bailout early. */ | 37 | /* Sanity checks. */ |
38 | if (pop3 == NULL || user == NULL || secret == NULL) | ||
39 | return MU_ERROR_INVALID_PARAMETER; | ||
40 | |||
41 | /* The server did not offer a timestamp in the greeting, bailout early. */ | ||
38 | if (pop3->timestamp == NULL) | 42 | if (pop3->timestamp == NULL) |
39 | return MU_ERROR_NOT_SUPPORTED; | 43 | return MU_ERROR_NOT_SUPPORTED; |
40 | 44 | ||
... | @@ -49,9 +53,6 @@ pop3_apop0 (pop3_t pop3, const char *user, const char *secret) | ... | @@ -49,9 +53,6 @@ pop3_apop0 (pop3_t pop3, const char *user, const char *secret) |
49 | char *tmp; | 53 | char *tmp; |
50 | size_t n; | 54 | size_t n; |
51 | 55 | ||
52 | if (user == NULL || secret == NULL) | ||
53 | return MU_ERROR_INVALID_PARAMETER; | ||
54 | |||
55 | MD5Init (&md5context); | 56 | MD5Init (&md5context); |
56 | MD5Update (&md5context, (unsigned char *)pop3->timestamp, | 57 | MD5Update (&md5context, (unsigned char *)pop3->timestamp, |
57 | strlen (pop3->timestamp)); | 58 | strlen (pop3->timestamp)); |
... | @@ -90,19 +91,3 @@ pop3_apop0 (pop3_t pop3, const char *user, const char *secret) | ... | @@ -90,19 +91,3 @@ pop3_apop0 (pop3_t pop3, const char *user, const char *secret) |
90 | 91 | ||
91 | return status; | 92 | return status; |
92 | } | 93 | } |
93 | |||
94 | int | ||
95 | pop3_apop (pop3_t pop3, const char *user, const char *secret) | ||
96 | { | ||
97 | int status; | ||
98 | |||
99 | if (pop3 == NULL) | ||
100 | return MU_ERROR_INVALID_PARAMETER; | ||
101 | |||
102 | monitor_lock (pop3->lock); | ||
103 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
104 | status = pop3_apop0 (pop3, user, secret); | ||
105 | monitor_unlock (pop3->lock); | ||
106 | monitor_cleanup_pop (0); | ||
107 | return status; | ||
108 | } | ... | ... |
... | @@ -24,11 +24,14 @@ | ... | @@ -24,11 +24,14 @@ |
24 | #include <stddef.h> | 24 | #include <stddef.h> |
25 | #include <mailutils/sys/pop3.h> | 25 | #include <mailutils/sys/pop3.h> |
26 | 26 | ||
27 | static int | 27 | int |
28 | pop3_capa0 (pop3_t pop3, iterator_t *piterator) | 28 | pop3_capa (pop3_t pop3, iterator_t *piterator) |
29 | { | 29 | { |
30 | int status; | 30 | int status; |
31 | 31 | ||
32 | if (pop3 == NULL || piterator == NULL) | ||
33 | return MU_ERROR_INVALID_PARAMETER; | ||
34 | |||
32 | switch (pop3->state) | 35 | switch (pop3->state) |
33 | { | 36 | { |
34 | case POP3_NO_STATE: | 37 | case POP3_NO_STATE: |
... | @@ -64,19 +67,3 @@ pop3_capa0 (pop3_t pop3, iterator_t *piterator) | ... | @@ -64,19 +67,3 @@ pop3_capa0 (pop3_t pop3, iterator_t *piterator) |
64 | 67 | ||
65 | return status; | 68 | return status; |
66 | } | 69 | } |
67 | |||
68 | int | ||
69 | pop3_capa (pop3_t pop3, iterator_t *piterator) | ||
70 | { | ||
71 | int status; | ||
72 | |||
73 | if (pop3 == NULL || piterator == NULL) | ||
74 | return MU_ERROR_INVALID_PARAMETER; | ||
75 | |||
76 | monitor_lock (pop3->lock); | ||
77 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
78 | status = pop3_capa0 (pop3, piterator); | ||
79 | monitor_unlock (pop3->lock); | ||
80 | monitor_cleanup_pop (0); | ||
81 | return status; | ||
82 | } | ... | ... |
mailbox2/pop3/pop3_carrier.c
0 → 100644
1 | /* GNU mailutils - a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001 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 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | |||
22 | #include <string.h> | ||
23 | #ifdef HAVE_STRINGS_H | ||
24 | # include <strings.h> | ||
25 | #endif | ||
26 | |||
27 | #include <stdlib.h> | ||
28 | #include <mailutils/sys/pop3.h> | ||
29 | |||
30 | int | ||
31 | pop3_set_carrier (pop3_t pop3, stream_t carrier) | ||
32 | { | ||
33 | /* Sanity checks. */ | ||
34 | if (pop3 == NULL) | ||
35 | return MU_ERROR_INVALID_PARAMETER; | ||
36 | |||
37 | if (pop3->carrier) | ||
38 | { | ||
39 | stream_close (pop3->carrier); | ||
40 | stream_release (pop3->carrier); | ||
41 | } | ||
42 | pop3->carrier = carrier; | ||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | int | ||
47 | pop3_get_carrier (pop3_t pop3, stream_t *pcarrier) | ||
48 | { | ||
49 | /* Sanity checks. */ | ||
50 | if (pop3 == NULL || pcarrier == NULL) | ||
51 | return MU_ERROR_INVALID_PARAMETER; | ||
52 | |||
53 | if (pop3->carrier == NULL) | ||
54 | { | ||
55 | stream_t carrier = NULL; | ||
56 | int status = stream_tcp_create (&carrier); | ||
57 | if (status != 0) | ||
58 | return status; | ||
59 | status = stream_buffer_create (&(pop3->carrier), carrier, 1024); | ||
60 | if (status != 0) | ||
61 | { | ||
62 | stream_release (carrier); | ||
63 | return status; | ||
64 | } | ||
65 | } | ||
66 | /* Incremente the ref count, since we are exposing it. */ | ||
67 | stream_add_ref (pop3->carrier); | ||
68 | *pcarrier = pop3->carrier; | ||
69 | return 0; | ||
70 | } |
... | @@ -33,11 +33,15 @@ static int pop3_sleep (int seconds); | ... | @@ -33,11 +33,15 @@ static int pop3_sleep (int seconds); |
33 | 33 | ||
34 | /* Open the connection to the server. The server sends an affirmative greeting | 34 | /* Open the connection to the server. The server sends an affirmative greeting |
35 | that may contain a timestamp for APOP. */ | 35 | that may contain a timestamp for APOP. */ |
36 | static int | 36 | int |
37 | pop3_connect0 (pop3_t pop3, const char *host, unsigned int port) | 37 | pop3_connect (pop3_t pop3, const char *host, unsigned int port) |
38 | { | 38 | { |
39 | int status; | 39 | int status; |
40 | 40 | ||
41 | /* Sanity checks. */ | ||
42 | if (pop3 == NULL || host == NULL) | ||
43 | return MU_ERROR_INVALID_PARAMETER; | ||
44 | |||
41 | /* Default is 110. */ | 45 | /* Default is 110. */ |
42 | if (!port) | 46 | if (!port) |
43 | port = 110; | 47 | port = 110; |
... | @@ -46,15 +50,18 @@ pop3_connect0 (pop3_t pop3, const char *host, unsigned int port) | ... | @@ -46,15 +50,18 @@ pop3_connect0 (pop3_t pop3, const char *host, unsigned int port) |
46 | switch (pop3->state) | 50 | switch (pop3->state) |
47 | { | 51 | { |
48 | default: | 52 | default: |
49 | /* __Fallthrough__, they want to clear an error. */ | 53 | /* FALLTHROUGH */ |
54 | /* If pop3 was in an error state going through here should clear it. */ | ||
55 | |||
50 | case POP3_NO_STATE: | 56 | case POP3_NO_STATE: |
51 | /* Create the networking stack. */ | 57 | /* Create the networking stack. */ |
52 | if (pop3->stream == NULL) | 58 | if (pop3->carrier == NULL) |
53 | { | 59 | { |
54 | status = stream_tcp_create (&(pop3->stream)); | 60 | stream_t carrier; |
61 | status = pop3_get_carrier (pop3, &carrier); | ||
55 | POP3_CHECK_ERROR (pop3, status); | 62 | POP3_CHECK_ERROR (pop3, status); |
56 | /* Using the awkward stream_t buffering. */ | 63 | /* A add_ref was done part of pop3_get_carrier(). */ |
57 | /*stream_setbufsiz (pop3->stream, 1024); */ | 64 | stream_release (carrier); |
58 | } | 65 | } |
59 | else | 66 | else |
60 | { | 67 | { |
... | @@ -65,8 +72,8 @@ pop3_connect0 (pop3_t pop3, const char *host, unsigned int port) | ... | @@ -65,8 +72,8 @@ pop3_connect0 (pop3_t pop3, const char *host, unsigned int port) |
65 | to read a new message, closing the connection and immediately | 72 | to read a new message, closing the connection and immediately |
66 | contacting the server again, and he'll end up having | 73 | contacting the server again, and he'll end up having |
67 | "-ERR Mail Lock busy" or something similar. To prevent this race | 74 | "-ERR Mail Lock busy" or something similar. To prevent this race |
68 | condition we sleep 2 seconds. This really obvious for in | 75 | condition we sleep 2 seconds. This is really obvious for in |
69 | environment where QPopper is use, the user as a big mailbox. */ | 76 | environment where QPopper is use and the user as a big mailbox. */ |
70 | pop3_disconnect (pop3); | 77 | pop3_disconnect (pop3); |
71 | pop3_sleep (2); | 78 | pop3_sleep (2); |
72 | } | 79 | } |
... | @@ -74,7 +81,7 @@ pop3_connect0 (pop3_t pop3, const char *host, unsigned int port) | ... | @@ -74,7 +81,7 @@ pop3_connect0 (pop3_t pop3, const char *host, unsigned int port) |
74 | 81 | ||
75 | case POP3_CONNECT: | 82 | case POP3_CONNECT: |
76 | /* Establish the connection. */ | 83 | /* Establish the connection. */ |
77 | status = stream_open (pop3->stream, host, port, | 84 | status = stream_open (pop3->carrier, host, port, |
78 | MU_STREAM_READ|MU_STREAM_WRITE); | 85 | MU_STREAM_READ|MU_STREAM_WRITE); |
79 | POP3_CHECK_EAGAIN (pop3, status); | 86 | POP3_CHECK_EAGAIN (pop3, status); |
80 | pop3->acknowledge = 0; | 87 | pop3->acknowledge = 0; |
... | @@ -89,7 +96,7 @@ pop3_connect0 (pop3_t pop3, const char *host, unsigned int port) | ... | @@ -89,7 +96,7 @@ pop3_connect0 (pop3_t pop3, const char *host, unsigned int port) |
89 | POP3_CHECK_EAGAIN (pop3, status); | 96 | POP3_CHECK_EAGAIN (pop3, status); |
90 | if (strncasecmp (pop3->ack.buf, "+OK", 3) != 0) | 97 | if (strncasecmp (pop3->ack.buf, "+OK", 3) != 0) |
91 | { | 98 | { |
92 | stream_close (pop3->stream); | 99 | stream_close (pop3->carrier); |
93 | pop3->state = POP3_NO_STATE; | 100 | pop3->state = POP3_NO_STATE; |
94 | return MU_ERROR_OPERATION_DENIED; | 101 | return MU_ERROR_OPERATION_DENIED; |
95 | } | 102 | } |
... | @@ -106,7 +113,7 @@ pop3_connect0 (pop3_t pop3, const char *host, unsigned int port) | ... | @@ -106,7 +113,7 @@ pop3_connect0 (pop3_t pop3, const char *host, unsigned int port) |
106 | pop3->timestamp = calloc (len + 1, 1); | 113 | pop3->timestamp = calloc (len + 1, 1); |
107 | if (pop3->timestamp == NULL) | 114 | if (pop3->timestamp == NULL) |
108 | { | 115 | { |
109 | stream_close (pop3->stream); | 116 | stream_close (pop3->carrier); |
110 | POP3_CHECK_ERROR (pop3, MU_ERROR_NO_MEMORY); | 117 | POP3_CHECK_ERROR (pop3, MU_ERROR_NO_MEMORY); |
111 | } | 118 | } |
112 | /* Do not copy the surrounding '<>'. */ | 119 | /* Do not copy the surrounding '<>'. */ |
... | @@ -130,21 +137,3 @@ pop3_sleep (int seconds) | ... | @@ -130,21 +137,3 @@ pop3_sleep (int seconds) |
130 | tval.tv_usec = 0; | 137 | tval.tv_usec = 0; |
131 | return select (1, NULL, NULL, NULL, &tval); | 138 | return select (1, NULL, NULL, NULL, &tval); |
132 | } | 139 | } |
133 | |||
134 | int | ||
135 | pop3_connect (pop3_t pop3, const char *host, unsigned int port) | ||
136 | { | ||
137 | int status; | ||
138 | |||
139 | /* Sanity checks. */ | ||
140 | if (pop3 == NULL || host == NULL) | ||
141 | return MU_ERROR_INVALID_PARAMETER; | ||
142 | |||
143 | monitor_lock (pop3->lock); | ||
144 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
145 | status = pop3_connect0 (pop3, host, port); | ||
146 | monitor_unlock (pop3->lock); | ||
147 | monitor_cleanup_pop (0); | ||
148 | return status; | ||
149 | |||
150 | } | ... | ... |
... | @@ -24,11 +24,13 @@ | ... | @@ -24,11 +24,13 @@ |
24 | #include <mailutils/sys/pop3.h> | 24 | #include <mailutils/sys/pop3.h> |
25 | 25 | ||
26 | /* Initialise a pop3_t handle. */ | 26 | /* Initialise a pop3_t handle. */ |
27 | |||
27 | int | 28 | int |
28 | pop3_create (pop3_t *ppop3) | 29 | pop3_create (pop3_t *ppop3) |
29 | { | 30 | { |
30 | pop3_t pop3; | 31 | pop3_t pop3; |
31 | 32 | ||
33 | /* Sanity check. */ | ||
32 | if (ppop3 == NULL) | 34 | if (ppop3 == NULL) |
33 | return MU_ERROR_INVALID_PARAMETER; | 35 | return MU_ERROR_INVALID_PARAMETER; |
34 | 36 | ||
... | @@ -36,32 +38,33 @@ pop3_create (pop3_t *ppop3) | ... | @@ -36,32 +38,33 @@ pop3_create (pop3_t *ppop3) |
36 | if (pop3 == NULL) | 38 | if (pop3 == NULL) |
37 | return MU_ERROR_NO_MEMORY; | 39 | return MU_ERROR_NO_MEMORY; |
38 | 40 | ||
41 | /* Reserve space for the ack(nowledgement) response. */ | ||
39 | /* According to RFC 2449: The maximum length of the first line of a | 42 | /* According to RFC 2449: The maximum length of the first line of a |
40 | command response (including the initial greeting) is unchanged at | 43 | command response (including the initial greeting) is unchanged at |
41 | 512 octets (including the terminating CRLF). */ | 44 | 512 octets (including the terminating CRLF). */ |
42 | pop3->ack.len = 512; | 45 | pop3->ack.len = 512; |
43 | pop3->ack.ptr = pop3->ack.buf = calloc (pop3->ack.len, 1); | 46 | pop3->ack.buf = calloc (pop3->ack.len, 1); |
44 | if (pop3->ack.buf == NULL) | 47 | if (pop3->ack.buf == NULL) |
45 | { | 48 | { |
46 | pop3_destroy (pop3); | 49 | pop3_destroy (pop3); |
47 | return MU_ERROR_NO_MEMORY; | 50 | return MU_ERROR_NO_MEMORY; |
48 | } | 51 | } |
52 | pop3->ack.ptr = pop3->ack.buf; | ||
49 | 53 | ||
50 | /* RFC 2449 recommands 255, but we grow it as needed. */ | 54 | /* RFC 2449 recommands 255, but we grow it as needed. */ |
51 | pop3->io.len = 255; | 55 | pop3->io.len = 255; |
52 | pop3->io.ptr = pop3->io.buf = calloc (pop3->io.len, 1); | 56 | pop3->io.buf = calloc (pop3->io.len, 1); |
53 | if (pop3->io.buf == NULL) | 57 | if (pop3->io.buf == NULL) |
54 | { | 58 | { |
55 | pop3_destroy (pop3); | 59 | pop3_destroy (pop3); |
56 | return MU_ERROR_NO_MEMORY; | 60 | return MU_ERROR_NO_MEMORY; |
57 | } | 61 | } |
62 | pop3->io.ptr = pop3->io.buf; | ||
58 | 63 | ||
59 | pop3->state = POP3_NO_STATE; /* Init with no state. */ | 64 | pop3->state = POP3_NO_STATE; /* Init with no state. */ |
60 | pop3->timeout = 10 * 60; /* The default Timeout is 10 minutes. */ | 65 | pop3->timeout = (10 * 60) * 100; /* The default Timeout is 10 minutes. */ |
61 | pop3->acknowledge = 0; /* No Ack received. */ | 66 | pop3->acknowledge = 0; /* No Ack received. */ |
62 | 67 | ||
63 | monitor_create (&(pop3->lock)); | ||
64 | |||
65 | *ppop3 = pop3; | 68 | *ppop3 = pop3; |
66 | return 0; /* Okdoke. */ | 69 | return 0; /* Okdoke. */ |
67 | } | 70 | } | ... | ... |
... | @@ -26,11 +26,14 @@ | ... | @@ -26,11 +26,14 @@ |
26 | 26 | ||
27 | #include <mailutils/sys/pop3.h> | 27 | #include <mailutils/sys/pop3.h> |
28 | 28 | ||
29 | static int | 29 | int |
30 | pop3_dele0 (pop3_t pop3, unsigned msgno) | 30 | pop3_dele (pop3_t pop3, unsigned msgno) |
31 | { | 31 | { |
32 | int status; | 32 | int status; |
33 | 33 | ||
34 | if (pop3 == NULL || msgno == 0) | ||
35 | return MU_ERROR_INVALID_PARAMETER; | ||
36 | |||
34 | switch (pop3->state) | 37 | switch (pop3->state) |
35 | { | 38 | { |
36 | case POP3_NO_STATE: | 39 | case POP3_NO_STATE: |
... | @@ -61,19 +64,3 @@ pop3_dele0 (pop3_t pop3, unsigned msgno) | ... | @@ -61,19 +64,3 @@ pop3_dele0 (pop3_t pop3, unsigned msgno) |
61 | } | 64 | } |
62 | return status; | 65 | return status; |
63 | } | 66 | } |
64 | |||
65 | int | ||
66 | pop3_dele (pop3_t pop3, unsigned msgno) | ||
67 | { | ||
68 | int status; | ||
69 | |||
70 | if (pop3 == NULL || msgno == 0) | ||
71 | return MU_ERROR_INVALID_PARAMETER; | ||
72 | |||
73 | monitor_lock (pop3->lock); | ||
74 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
75 | status = pop3_dele0 (pop3, msgno); | ||
76 | monitor_unlock (pop3->lock); | ||
77 | monitor_cleanup_pop (0); | ||
78 | return status; | ||
79 | } | ... | ... |
... | @@ -23,7 +23,7 @@ | ... | @@ -23,7 +23,7 @@ |
23 | #include <mailutils/sys/pop3.h> | 23 | #include <mailutils/sys/pop3.h> |
24 | #include <stdlib.h> | 24 | #include <stdlib.h> |
25 | 25 | ||
26 | void | 26 | int |
27 | pop3_destroy (pop3_t pop3) | 27 | pop3_destroy (pop3_t pop3) |
28 | { | 28 | { |
29 | if (pop3) | 29 | if (pop3) |
... | @@ -37,8 +37,7 @@ pop3_destroy (pop3_t pop3) | ... | @@ -37,8 +37,7 @@ pop3_destroy (pop3_t pop3) |
37 | if (pop3->timestamp) | 37 | if (pop3->timestamp) |
38 | free (pop3->timestamp); | 38 | free (pop3->timestamp); |
39 | 39 | ||
40 | monitor_destroy (pop3->lock); | ||
41 | |||
42 | free (pop3); | 40 | free (pop3); |
43 | } | 41 | } |
42 | return 0; | ||
44 | } | 43 | } | ... | ... |
... | @@ -23,10 +23,14 @@ | ... | @@ -23,10 +23,14 @@ |
23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | #include <string.h> | 24 | #include <string.h> |
25 | 25 | ||
26 | /* Sudden death. */ | 26 | int |
27 | static int | 27 | pop3_disconnect (pop3_t pop3) |
28 | pop3_disconnect0 (pop3_t pop3) | ||
29 | { | 28 | { |
29 | |||
30 | /* Sanity checks. */ | ||
31 | if (pop3 == NULL) | ||
32 | return MU_ERROR_INVALID_PARAMETER; | ||
33 | |||
30 | /* We can keep some of the fields, if they decide to pop3_open() again but | 34 | /* We can keep some of the fields, if they decide to pop3_open() again but |
31 | clear the states. */ | 35 | clear the states. */ |
32 | pop3->state = POP3_NO_STATE; | 36 | pop3->state = POP3_NO_STATE; |
... | @@ -40,24 +44,7 @@ pop3_disconnect0 (pop3_t pop3) | ... | @@ -40,24 +44,7 @@ pop3_disconnect0 (pop3_t pop3) |
40 | free (pop3->timestamp); | 44 | free (pop3->timestamp); |
41 | pop3->timestamp = NULL; | 45 | pop3->timestamp = NULL; |
42 | } | 46 | } |
43 | if (pop3->stream) | 47 | if (pop3->carrier) |
44 | return stream_close (pop3->stream); | 48 | return stream_close (pop3->carrier); |
45 | return 0; | 49 | return 0; |
46 | } | 50 | } |
47 | |||
48 | int | ||
49 | pop3_disconnect (pop3_t pop3) | ||
50 | { | ||
51 | int status; | ||
52 | |||
53 | /* Sanity checks. */ | ||
54 | if (pop3 == NULL) | ||
55 | return MU_ERROR_INVALID_PARAMETER; | ||
56 | |||
57 | monitor_lock (pop3->lock); | ||
58 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
59 | status = pop3_disconnect0 (pop3); | ||
60 | monitor_unlock (pop3->lock); | ||
61 | monitor_cleanup_pop (0); | ||
62 | return status; | ||
63 | } | ... | ... |
... | @@ -123,7 +123,6 @@ p_destroy (iterator_t iterator) | ... | @@ -123,7 +123,6 @@ p_destroy (iterator_t iterator) |
123 | return 0; | 123 | return 0; |
124 | } | 124 | } |
125 | 125 | ||
126 | |||
127 | static int | 126 | static int |
128 | p_first (iterator_t iterator) | 127 | p_first (iterator_t iterator) |
129 | { | 128 | { |
... | @@ -149,108 +148,20 @@ p_next (iterator_t iterator) | ... | @@ -149,108 +148,20 @@ p_next (iterator_t iterator) |
149 | { | 148 | { |
150 | if (n) | 149 | if (n) |
151 | { | 150 | { |
152 | switch (p_iterator->pop3->state) | 151 | char *buf; |
152 | buf = calloc (n + 1, 1); | ||
153 | if (buf) | ||
153 | { | 154 | { |
154 | case POP3_CAPA_RX: | 155 | /* Consume. */ |
155 | { | 156 | pop3_readline (p_iterator->pop3, buf, n + 1, NULL); |
156 | char *buf; | 157 | if (buf[n - 1] == '\n') |
157 | buf = calloc (n + 1, 1); | 158 | buf[n - 1] = '\0'; |
158 | if (buf) | 159 | if (p_iterator->item) |
159 | { | 160 | free (p_iterator->item); |
160 | /* Consume. */ | 161 | p_iterator->item = buf; |
161 | pop3_readline (p_iterator->pop3, buf, n + 1, NULL); | ||
162 | if (buf[n - 1] == '\n') | ||
163 | buf[n - 1] = '\0'; | ||
164 | if (p_iterator->item) | ||
165 | free (p_iterator->item); | ||
166 | p_iterator->item = buf; | ||
167 | } | ||
168 | else | ||
169 | status = MU_ERROR_NO_MEMORY; | ||
170 | break; | ||
171 | } | ||
172 | |||
173 | case POP3_UIDL_RX: | ||
174 | { | ||
175 | struct pop3_uidl_item *pitem; | ||
176 | char *buf = calloc (n + 1, 1); | ||
177 | if (buf) | ||
178 | { | ||
179 | if (p_iterator->item) | ||
180 | { | ||
181 | pitem = p_iterator->item; | ||
182 | if (pitem->uidl) | ||
183 | free (pitem->uidl); | ||
184 | free (pitem); | ||
185 | } | ||
186 | p_iterator->item = calloc (1, sizeof *pitem); | ||
187 | pitem = p_iterator->item; | ||
188 | if (pitem) | ||
189 | { | ||
190 | unsigned msgno; | ||
191 | char *space; | ||
192 | /* Consume. */ | ||
193 | pop3_readline (p_iterator->pop3, buf, | ||
194 | n + 1, NULL); | ||
195 | msgno = 0; | ||
196 | /* The format is: | ||
197 | msgno uidlsttring */ | ||
198 | space = strchr (buf, ' '); | ||
199 | if (space) | ||
200 | { | ||
201 | *space++ = '\0'; | ||
202 | msgno = strtoul (buf, NULL, 10); | ||
203 | } | ||
204 | if (space && space[strlen (space) - 1] == '\n') | ||
205 | space[strlen (space) - 1] = '\0'; | ||
206 | if (space == NULL) | ||
207 | space = (char *)""; | ||
208 | pitem->msgno = msgno; | ||
209 | pitem->uidl = strdup (space); | ||
210 | } | ||
211 | else | ||
212 | status = MU_ERROR_NO_MEMORY; | ||
213 | free (buf); | ||
214 | } | ||
215 | else | ||
216 | status = MU_ERROR_NO_MEMORY; | ||
217 | break; | ||
218 | } | ||
219 | |||
220 | case POP3_LIST_RX: | ||
221 | { | ||
222 | struct pop3_list_item *pitem; | ||
223 | char *buf = calloc (n + 1, 1); | ||
224 | |||
225 | if (buf) | ||
226 | { | ||
227 | if (p_iterator->item) | ||
228 | free (p_iterator->item); | ||
229 | pitem = calloc (1, sizeof *pitem); | ||
230 | p_iterator->item = pitem; | ||
231 | if (pitem) | ||
232 | { | ||
233 | unsigned msgno; | ||
234 | size_t size; | ||
235 | /* Consume. */ | ||
236 | pop3_readline (p_iterator->pop3, buf, | ||
237 | n + 1, NULL); | ||
238 | size = msgno = 0; | ||
239 | sscanf (buf, "%d %d", &msgno, &size); | ||
240 | pitem->msgno = msgno; | ||
241 | pitem->size = size; | ||
242 | } | ||
243 | else | ||
244 | status = MU_ERROR_NO_MEMORY; | ||
245 | free (buf); | ||
246 | } | ||
247 | else | ||
248 | status = MU_ERROR_NO_MEMORY; | ||
249 | break; | ||
250 | } | ||
251 | |||
252 | default: | ||
253 | } | 162 | } |
163 | else | ||
164 | status = MU_ERROR_NO_MEMORY; | ||
254 | } | 165 | } |
255 | else | 166 | else |
256 | { | 167 | { |
... | @@ -287,21 +198,9 @@ p_current (iterator_t iterator, void *item) | ... | @@ -287,21 +198,9 @@ p_current (iterator_t iterator, void *item) |
287 | monitor_lock (p_iterator->lock); | 198 | monitor_lock (p_iterator->lock); |
288 | if (item) | 199 | if (item) |
289 | { | 200 | { |
290 | switch (p_iterator->pop3->state) | 201 | *((char **)item) = p_iterator->item; |
291 | { | 202 | p_iterator->item = NULL; |
292 | case POP3_CAPA_RX: | ||
293 | case POP3_UIDL_RX: | ||
294 | *((char **)item) = p_iterator->item; | ||
295 | break; | ||
296 | |||
297 | case POP3_LIST_RX: | ||
298 | *((struct pop3_list_item **)item) = p_iterator->item; | ||
299 | break; | ||
300 | |||
301 | default: | ||
302 | } | ||
303 | } | 203 | } |
304 | p_iterator->item = NULL; | ||
305 | monitor_unlock (p_iterator->lock); | 204 | monitor_unlock (p_iterator->lock); |
306 | } | 205 | } |
307 | return 0; | 206 | return 0; | ... | ... |
... | @@ -28,11 +28,14 @@ | ... | @@ -28,11 +28,14 @@ |
28 | #include <stdio.h> | 28 | #include <stdio.h> |
29 | #include <mailutils/sys/pop3.h> | 29 | #include <mailutils/sys/pop3.h> |
30 | 30 | ||
31 | static int | 31 | int |
32 | pop3_list0 (pop3_t pop3, unsigned msgno, size_t *psize) | 32 | pop3_list (pop3_t pop3, unsigned int msgno, size_t *psize) |
33 | { | 33 | { |
34 | int status; | 34 | int status; |
35 | 35 | ||
36 | if (pop3 == NULL || msgno == 0 || psize == NULL) | ||
37 | return MU_ERROR_INVALID_PARAMETER; | ||
38 | |||
36 | switch (pop3->state) | 39 | switch (pop3->state) |
37 | { | 40 | { |
38 | case POP3_NO_STATE: | 41 | case POP3_NO_STATE: |
... | @@ -70,18 +73,3 @@ pop3_list0 (pop3_t pop3, unsigned msgno, size_t *psize) | ... | @@ -70,18 +73,3 @@ pop3_list0 (pop3_t pop3, unsigned msgno, size_t *psize) |
70 | 73 | ||
71 | return status; | 74 | return status; |
72 | } | 75 | } |
73 | |||
74 | int | ||
75 | pop3_list (pop3_t pop3, unsigned msgno, size_t *psize) | ||
76 | { | ||
77 | int status; | ||
78 | if (pop3 == NULL) | ||
79 | return MU_ERROR_INVALID_PARAMETER; | ||
80 | |||
81 | monitor_lock (pop3->lock); | ||
82 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
83 | status = pop3_list0 (pop3, msgno, psize); | ||
84 | monitor_unlock (pop3->lock); | ||
85 | monitor_cleanup_pop (0); | ||
86 | return status; | ||
87 | } | ... | ... |
... | @@ -25,19 +25,21 @@ | ... | @@ -25,19 +25,21 @@ |
25 | # include <strings.h> | 25 | # include <strings.h> |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | #include <stdio.h> | ||
28 | #include <stdlib.h> | 29 | #include <stdlib.h> |
29 | #include <mailutils/sys/pop3.h> | 30 | #include <mailutils/sys/pop3.h> |
30 | 31 | ||
31 | static int | 32 | int |
32 | pop3_list_all0 (pop3_t pop3, iterator_t *piterator) | 33 | pop3_list_all (pop3_t pop3, iterator_t *piterator) |
33 | { | 34 | { |
34 | int status; | 35 | int status; |
35 | 36 | ||
37 | if (pop3 == NULL || piterator == NULL) | ||
38 | return MU_ERROR_INVALID_PARAMETER; | ||
39 | |||
36 | switch (pop3->state) | 40 | switch (pop3->state) |
37 | { | 41 | { |
38 | case POP3_NO_STATE: | 42 | case POP3_NO_STATE: |
39 | if (piterator == NULL) | ||
40 | return MU_ERROR_INVALID_PARAMETER; | ||
41 | status = pop3_writeline (pop3, "LIST\r\n"); | 43 | status = pop3_writeline (pop3, "LIST\r\n"); |
42 | POP3_CHECK_ERROR (pop3, status); | 44 | POP3_CHECK_ERROR (pop3, status); |
43 | pop3->state = POP3_LIST; | 45 | pop3->state = POP3_LIST; |
... | @@ -72,17 +74,21 @@ pop3_list_all0 (pop3_t pop3, iterator_t *piterator) | ... | @@ -72,17 +74,21 @@ pop3_list_all0 (pop3_t pop3, iterator_t *piterator) |
72 | } | 74 | } |
73 | 75 | ||
74 | int | 76 | int |
75 | pop3_list_all (pop3_t pop3, iterator_t *piterator) | 77 | pop3_list_current (iterator_t iterator, unsigned int *pno, size_t *plen) |
76 | { | 78 | { |
77 | int status; | 79 | char *buf; |
78 | 80 | int status = iterator_current (iterator, (void *)&buf); | |
79 | if (pop3 == NULL) | 81 | if (status == 0) |
80 | return MU_ERROR_INVALID_PARAMETER; | 82 | { |
81 | 83 | size_t size; | |
82 | monitor_lock (pop3->lock); | 84 | unsigned int msgno; |
83 | monitor_cleanup_push (pop3_cleanup, pop3); | 85 | size = msgno = 0; |
84 | status = pop3_list_all0 (pop3, piterator); | 86 | sscanf (buf, "%d %d", &msgno, &size); |
85 | monitor_unlock (pop3->lock); | 87 | if (pno) |
86 | monitor_cleanup_pop (0); | 88 | *pno = msgno; |
89 | if (plen) | ||
90 | *plen = size; | ||
91 | free (buf); | ||
92 | } | ||
87 | return status; | 93 | return status; |
88 | } | 94 | } | ... | ... |
... | @@ -27,11 +27,14 @@ | ... | @@ -27,11 +27,14 @@ |
27 | 27 | ||
28 | #include <mailutils/sys/pop3.h> | 28 | #include <mailutils/sys/pop3.h> |
29 | 29 | ||
30 | static int | 30 | int |
31 | pop3_noop0 (pop3_t pop3) | 31 | pop3_noop (pop3_t pop3) |
32 | { | 32 | { |
33 | int status; | 33 | int status; |
34 | 34 | ||
35 | if (pop3 == NULL) | ||
36 | return MU_ERROR_INVALID_PARAMETER; | ||
37 | |||
35 | switch (pop3->state) | 38 | switch (pop3->state) |
36 | { | 39 | { |
37 | case POP3_NO_STATE: | 40 | case POP3_NO_STATE: |
... | @@ -63,20 +66,3 @@ pop3_noop0 (pop3_t pop3) | ... | @@ -63,20 +66,3 @@ pop3_noop0 (pop3_t pop3) |
63 | 66 | ||
64 | return status; | 67 | return status; |
65 | } | 68 | } |
66 | |||
67 | |||
68 | int | ||
69 | pop3_noop (pop3_t pop3) | ||
70 | { | ||
71 | int status; | ||
72 | |||
73 | if (pop3 == NULL) | ||
74 | return MU_ERROR_INVALID_PARAMETER; | ||
75 | |||
76 | monitor_lock (pop3->lock); | ||
77 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
78 | status = pop3_noop0 (pop3); | ||
79 | monitor_unlock (pop3->lock); | ||
80 | monitor_cleanup_pop (0); | ||
81 | return status; | ||
82 | } | ... | ... |
... | @@ -27,16 +27,17 @@ | ... | @@ -27,16 +27,17 @@ |
27 | 27 | ||
28 | #include <mailutils/sys/pop3.h> | 28 | #include <mailutils/sys/pop3.h> |
29 | 29 | ||
30 | static int | 30 | int |
31 | pop3_pass0 (pop3_t pop3, const char *passwd) | 31 | pop3_pass (pop3_t pop3, const char *passwd) |
32 | { | 32 | { |
33 | int status; | 33 | int status; |
34 | 34 | ||
35 | if (pop3 == NULL || passwd == NULL) | ||
36 | return MU_ERROR_INVALID_PARAMETER; | ||
37 | |||
35 | switch (pop3->state) | 38 | switch (pop3->state) |
36 | { | 39 | { |
37 | case POP3_NO_STATE: | 40 | case POP3_NO_STATE: |
38 | if (passwd == NULL) | ||
39 | return MU_ERROR_INVALID_PARAMETER; | ||
40 | status = pop3_writeline (pop3, "PASS %s\r\n", passwd); | 41 | status = pop3_writeline (pop3, "PASS %s\r\n", passwd); |
41 | POP3_CHECK_ERROR (pop3, status); | 42 | POP3_CHECK_ERROR (pop3, status); |
42 | pop3->state = POP3_PASS; | 43 | pop3->state = POP3_PASS; |
... | @@ -65,19 +66,3 @@ pop3_pass0 (pop3_t pop3, const char *passwd) | ... | @@ -65,19 +66,3 @@ pop3_pass0 (pop3_t pop3, const char *passwd) |
65 | 66 | ||
66 | return status; | 67 | return status; |
67 | } | 68 | } |
68 | |||
69 | int | ||
70 | pop3_pass (pop3_t pop3, const char *passwd) | ||
71 | { | ||
72 | int status; | ||
73 | |||
74 | if (pop3 == NULL) | ||
75 | return MU_ERROR_INVALID_PARAMETER; | ||
76 | |||
77 | monitor_lock (pop3->lock); | ||
78 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
79 | status = pop3_pass0 (pop3, passwd); | ||
80 | monitor_unlock (pop3->lock); | ||
81 | monitor_cleanup_pop (0); | ||
82 | return status; | ||
83 | } | ... | ... |
... | @@ -27,11 +27,14 @@ | ... | @@ -27,11 +27,14 @@ |
27 | 27 | ||
28 | #include <mailutils/sys/pop3.h> | 28 | #include <mailutils/sys/pop3.h> |
29 | 29 | ||
30 | static int | 30 | int |
31 | pop3_quit0 (pop3_t pop3) | 31 | pop3_quit (pop3_t pop3) |
32 | { | 32 | { |
33 | int status; | 33 | int status; |
34 | 34 | ||
35 | if (pop3 == NULL) | ||
36 | return MU_ERROR_INVALID_PARAMETER; | ||
37 | |||
35 | switch (pop3->state) | 38 | switch (pop3->state) |
36 | { | 39 | { |
37 | case POP3_NO_STATE: | 40 | case POP3_NO_STATE: |
... | @@ -58,19 +61,3 @@ pop3_quit0 (pop3_t pop3) | ... | @@ -58,19 +61,3 @@ pop3_quit0 (pop3_t pop3) |
58 | 61 | ||
59 | return status; | 62 | return status; |
60 | } | 63 | } |
61 | |||
62 | int | ||
63 | pop3_quit (pop3_t pop3) | ||
64 | { | ||
65 | int status; | ||
66 | |||
67 | if (pop3 == NULL) | ||
68 | return MU_ERROR_INVALID_PARAMETER; | ||
69 | |||
70 | monitor_lock (pop3->lock); | ||
71 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
72 | status = pop3_quit0 (pop3); | ||
73 | monitor_unlock (pop3->lock); | ||
74 | monitor_cleanup_pop (0); | ||
75 | return status; | ||
76 | } | ... | ... |
... | @@ -19,9 +19,9 @@ | ... | @@ -19,9 +19,9 @@ |
19 | # include <config.h> | 19 | # include <config.h> |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #include <stdio.h> | ||
22 | #include <stdlib.h> | 23 | #include <stdlib.h> |
23 | #include <string.h> | 24 | #include <string.h> |
24 | #include <sys/time.h> | ||
25 | #include <sys/types.h> | 25 | #include <sys/types.h> |
26 | #include <unistd.h> | 26 | #include <unistd.h> |
27 | #include <mailutils/sys/pop3.h> | 27 | #include <mailutils/sys/pop3.h> |
... | @@ -29,7 +29,7 @@ | ... | @@ -29,7 +29,7 @@ |
29 | 29 | ||
30 | /* Read a complete line from the pop server. Transform CRLF to LF, remove | 30 | /* Read a complete line from the pop server. Transform CRLF to LF, remove |
31 | the stuff byte termination octet ".", put a null in the buffer | 31 | the stuff byte termination octet ".", put a null in the buffer |
32 | when done. */ | 32 | when done. And Do a select() (stream_is_readready()) for the timeout. */ |
33 | static int | 33 | static int |
34 | pop3_getline (pop3_t pop3) | 34 | pop3_getline (pop3_t pop3) |
35 | { | 35 | { |
... | @@ -44,38 +44,12 @@ pop3_getline (pop3_t pop3) | ... | @@ -44,38 +44,12 @@ pop3_getline (pop3_t pop3) |
44 | since on linux tv is modified when error. */ | 44 | since on linux tv is modified when error. */ |
45 | if (pop3->timeout) | 45 | if (pop3->timeout) |
46 | { | 46 | { |
47 | /* Heavy hand but continue if select trip on a signal. */ | 47 | int ready = stream_is_readready (pop3->carrier, pop3->timeout); |
48 | for (;;) | 48 | if (ready == 0) |
49 | { | 49 | return MU_ERROR_TIMEOUT; |
50 | int fd = -1; | ||
51 | struct timeval tv; | ||
52 | fd_set rfds; | ||
53 | |||
54 | status = stream_get_fd (pop3->stream, &fd); | ||
55 | if (status != 0) | ||
56 | return status; | ||
57 | |||
58 | if (fd == -1) | ||
59 | return MU_ERROR_IO; | ||
60 | |||
61 | FD_ZERO (&rfds); | ||
62 | FD_SET (fd, &rfds); | ||
63 | tv.tv_sec = pop3->timeout; | ||
64 | tv.tv_usec = 0; | ||
65 | status = select (fd + 1, &rfds, NULL, NULL, &tv); | ||
66 | if (status == 0) | ||
67 | return MU_ERROR_TIMEOUT; | ||
68 | else if (status == -1) | ||
69 | { | ||
70 | if (errno == EINTR) | ||
71 | continue; | ||
72 | return MU_ERROR_IO; | ||
73 | } | ||
74 | break; | ||
75 | } | ||
76 | } | 50 | } |
77 | 51 | ||
78 | status = stream_readline (pop3->stream, pop3->io.buf + total, | 52 | status = stream_readline (pop3->carrier, pop3->io.buf + total, |
79 | pop3->io.len - total, &n); | 53 | pop3->io.len - total, &n); |
80 | if (status != 0) | 54 | if (status != 0) |
81 | return status; | 55 | return status; |
... | @@ -90,7 +64,7 @@ pop3_getline (pop3_t pop3) | ... | @@ -90,7 +64,7 @@ pop3_getline (pop3_t pop3) |
90 | if (pop3->io.nl == NULL) /* Do we have a full line. */ | 64 | if (pop3->io.nl == NULL) /* Do we have a full line. */ |
91 | { | 65 | { |
92 | /* Allocate a bigger buffer ? */ | 66 | /* Allocate a bigger buffer ? */ |
93 | if (total >= pop3->io.len -1) | 67 | if (total >= pop3->io.len - 1) |
94 | { | 68 | { |
95 | pop3->io.len *= 2; | 69 | pop3->io.len *= 2; |
96 | pop3->io.buf = realloc (pop3->io.buf, pop3->io.len + 1); | 70 | pop3->io.buf = realloc (pop3->io.buf, pop3->io.len + 1); |
... | @@ -134,6 +108,11 @@ pop3_getline (pop3_t pop3) | ... | @@ -134,6 +108,11 @@ pop3_getline (pop3_t pop3) |
134 | return status; | 108 | return status; |
135 | } /* if need to fill up. */ | 109 | } /* if need to fill up. */ |
136 | 110 | ||
111 | /* Call pop3_getline() for the dirty work, and consume i.e. put | ||
112 | in the user buffer only buflen. If buflen == 0 or buffer == NULL | ||
113 | nothing is consume, the data is save for another call to pop3_readline() | ||
114 | with a buffer != NULL. | ||
115 | */ | ||
137 | int | 116 | int |
138 | pop3_readline (pop3_t pop3, char *buffer, size_t buflen, size_t *pnread) | 117 | pop3_readline (pop3_t pop3, char *buffer, size_t buflen, size_t *pnread) |
139 | { | 118 | { |
... | @@ -142,7 +121,7 @@ pop3_readline (pop3_t pop3, char *buffer, size_t buflen, size_t *pnread) | ... | @@ -142,7 +121,7 @@ pop3_readline (pop3_t pop3, char *buffer, size_t buflen, size_t *pnread) |
142 | int status; | 121 | int status; |
143 | 122 | ||
144 | /* Do we need to fill up? Yes if no NL or the buffer is empty. */ | 123 | /* Do we need to fill up? Yes if no NL or the buffer is empty. */ |
145 | if (pop3->stream && (pop3->io.nl == NULL || pop3->io.ptr == pop3->io.buf)) | 124 | if (pop3->carrier && (pop3->io.nl == NULL || pop3->io.ptr == pop3->io.buf)) |
146 | { | 125 | { |
147 | status = pop3_getline (pop3); | 126 | status = pop3_getline (pop3); |
148 | if (status != 0) | 127 | if (status != 0) | ... | ... |
... | @@ -27,11 +27,14 @@ | ... | @@ -27,11 +27,14 @@ |
27 | 27 | ||
28 | #include <mailutils/sys/pop3.h> | 28 | #include <mailutils/sys/pop3.h> |
29 | 29 | ||
30 | static int | 30 | int |
31 | pop3_retr0 (pop3_t pop3, unsigned msgno, stream_t *pstream) | 31 | pop3_retr (pop3_t pop3, unsigned int msgno, stream_t *pstream) |
32 | { | 32 | { |
33 | int status; | 33 | int status; |
34 | 34 | ||
35 | if (pop3 == NULL || msgno == 0 || pstream == NULL) | ||
36 | return MU_ERROR_INVALID_PARAMETER; | ||
37 | |||
35 | switch (pop3->state) | 38 | switch (pop3->state) |
36 | { | 39 | { |
37 | case POP3_NO_STATE: | 40 | case POP3_NO_STATE: |
... | @@ -67,19 +70,3 @@ pop3_retr0 (pop3_t pop3, unsigned msgno, stream_t *pstream) | ... | @@ -67,19 +70,3 @@ pop3_retr0 (pop3_t pop3, unsigned msgno, stream_t *pstream) |
67 | 70 | ||
68 | return status; | 71 | return status; |
69 | } | 72 | } |
70 | |||
71 | int | ||
72 | pop3_retr (pop3_t pop3, unsigned msgno, stream_t *pstream) | ||
73 | { | ||
74 | int status; | ||
75 | |||
76 | if (pop3 == NULL || pstream == NULL) | ||
77 | return MU_ERROR_INVALID_PARAMETER; | ||
78 | |||
79 | monitor_lock (pop3->lock); | ||
80 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
81 | status = pop3_retr0 (pop3, msgno, pstream); | ||
82 | monitor_unlock (pop3->lock); | ||
83 | monitor_cleanup_pop (0); | ||
84 | return status; | ||
85 | } | ... | ... |
... | @@ -27,11 +27,14 @@ | ... | @@ -27,11 +27,14 @@ |
27 | 27 | ||
28 | #include <mailutils/sys/pop3.h> | 28 | #include <mailutils/sys/pop3.h> |
29 | 29 | ||
30 | static int | 30 | int |
31 | pop3_rset0 (pop3_t pop3) | 31 | pop3_rset (pop3_t pop3) |
32 | { | 32 | { |
33 | int status; | 33 | int status; |
34 | 34 | ||
35 | if (pop3 == NULL) | ||
36 | return MU_ERROR_INVALID_PARAMETER; | ||
37 | |||
35 | switch (pop3->state) | 38 | switch (pop3->state) |
36 | { | 39 | { |
37 | case POP3_NO_STATE: | 40 | case POP3_NO_STATE: |
... | @@ -63,19 +66,3 @@ pop3_rset0 (pop3_t pop3) | ... | @@ -63,19 +66,3 @@ pop3_rset0 (pop3_t pop3) |
63 | 66 | ||
64 | return status; | 67 | return status; |
65 | } | 68 | } |
66 | |||
67 | int | ||
68 | pop3_rset (pop3_t pop3) | ||
69 | { | ||
70 | int status; | ||
71 | |||
72 | if (pop3 == NULL) | ||
73 | return MU_ERROR_INVALID_PARAMETER; | ||
74 | |||
75 | monitor_lock (pop3->lock); | ||
76 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
77 | status = pop3_rset0 (pop3); | ||
78 | monitor_unlock (pop3->lock); | ||
79 | monitor_cleanup_pop (0); | ||
80 | return status; | ||
81 | } | ... | ... |
... | @@ -40,7 +40,7 @@ int | ... | @@ -40,7 +40,7 @@ int |
40 | pop3_send (pop3_t pop3) | 40 | pop3_send (pop3_t pop3) |
41 | { | 41 | { |
42 | int status = 0; | 42 | int status = 0; |
43 | if (pop3->stream && (pop3->io.ptr > pop3->io.buf)) | 43 | if (pop3->carrier && (pop3->io.ptr > pop3->io.buf)) |
44 | { | 44 | { |
45 | size_t n = 0; | 45 | size_t n = 0; |
46 | size_t len = pop3->io.ptr - pop3->io.buf; | 46 | size_t len = pop3->io.ptr - pop3->io.buf; |
... | @@ -49,34 +49,12 @@ pop3_send (pop3_t pop3) | ... | @@ -49,34 +49,12 @@ pop3_send (pop3_t pop3) |
49 | since on linux tv is modified when error. */ | 49 | since on linux tv is modified when error. */ |
50 | if (pop3->timeout) | 50 | if (pop3->timeout) |
51 | { | 51 | { |
52 | for (;;) | 52 | int ready = stream_is_writeready (pop3->carrier, pop3->timeout); |
53 | { | 53 | if (ready == 0) |
54 | int fd = -1; | 54 | return MU_ERROR_TIMEOUT; |
55 | struct timeval tv; | ||
56 | fd_set wfds; | ||
57 | status = stream_get_fd (pop3->stream, &fd); | ||
58 | if (status != 0) | ||
59 | return status; | ||
60 | |||
61 | FD_ZERO (&wfds); | ||
62 | FD_SET (fd, &wfds); | ||
63 | tv.tv_sec = pop3->timeout; | ||
64 | tv.tv_usec = 0; | ||
65 | |||
66 | status = select (fd + 1, NULL, &wfds, NULL, &tv); | ||
67 | if (status == 0) | ||
68 | return MU_ERROR_TIMEOUT; | ||
69 | else if (status == -1) | ||
70 | { | ||
71 | if (errno == EINTR) | ||
72 | continue; | ||
73 | return MU_ERROR_IO; | ||
74 | } | ||
75 | break; | ||
76 | } | ||
77 | } | 55 | } |
78 | 56 | ||
79 | status = stream_write (pop3->stream, pop3->io.buf, len, &n); | 57 | status = stream_write (pop3->carrier, pop3->io.buf, len, &n); |
80 | if (n) | 58 | if (n) |
81 | { | 59 | { |
82 | /* Consume what we sent. */ | 60 | /* Consume what we sent. */ | ... | ... |
... | @@ -28,16 +28,17 @@ | ... | @@ -28,16 +28,17 @@ |
28 | 28 | ||
29 | #include <mailutils/sys/pop3.h> | 29 | #include <mailutils/sys/pop3.h> |
30 | 30 | ||
31 | static int | 31 | int |
32 | pop3_stat0 (pop3_t pop3, unsigned *msg_count, size_t *size) | 32 | pop3_stat (pop3_t pop3, unsigned *msg_count, size_t *size) |
33 | { | 33 | { |
34 | int status; | 34 | int status; |
35 | 35 | ||
36 | if (pop3 == NULL || msg_count == NULL || size == NULL) | ||
37 | return MU_ERROR_INVALID_PARAMETER; | ||
38 | |||
36 | switch (pop3->state) | 39 | switch (pop3->state) |
37 | { | 40 | { |
38 | case POP3_NO_STATE: | 41 | case POP3_NO_STATE: |
39 | if (msg_count == NULL || size == NULL) | ||
40 | return MU_ERROR_INVALID_PARAMETER; | ||
41 | status = pop3_writeline (pop3, "STAT\r\n"); | 42 | status = pop3_writeline (pop3, "STAT\r\n"); |
42 | POP3_CHECK_ERROR (pop3, status); | 43 | POP3_CHECK_ERROR (pop3, status); |
43 | pop3->state = POP3_STAT; | 44 | pop3->state = POP3_STAT; |
... | @@ -71,19 +72,3 @@ pop3_stat0 (pop3_t pop3, unsigned *msg_count, size_t *size) | ... | @@ -71,19 +72,3 @@ pop3_stat0 (pop3_t pop3, unsigned *msg_count, size_t *size) |
71 | 72 | ||
72 | return status; | 73 | return status; |
73 | } | 74 | } |
74 | |||
75 | int | ||
76 | pop3_stat (pop3_t pop3, unsigned *msg_count, size_t *size) | ||
77 | { | ||
78 | int status; | ||
79 | |||
80 | if (pop3 == NULL) | ||
81 | return MU_ERROR_INVALID_PARAMETER; | ||
82 | |||
83 | monitor_lock (pop3->lock); | ||
84 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
85 | status = pop3_stat0 (pop3, msg_count, size); | ||
86 | monitor_unlock (pop3->lock); | ||
87 | monitor_cleanup_pop (0); | ||
88 | return status; | ||
89 | } | ... | ... |
... | @@ -27,37 +27,6 @@ | ... | @@ -27,37 +27,6 @@ |
27 | #include <stdlib.h> | 27 | #include <stdlib.h> |
28 | #include <mailutils/sys/pop3.h> | 28 | #include <mailutils/sys/pop3.h> |
29 | 29 | ||
30 | int | ||
31 | pop3_set_stream (pop3_t pop3, stream_t stream) | ||
32 | { | ||
33 | /* Sanity checks. */ | ||
34 | if (pop3 == NULL) | ||
35 | return MU_ERROR_INVALID_PARAMETER; | ||
36 | |||
37 | /* If the stream was set before we will leak. But do what they say. */ | ||
38 | pop3->stream = stream; | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | int | ||
43 | pop3_get_stream (pop3_t pop3, stream_t *pstream) | ||
44 | { | ||
45 | /* Sanity checks. */ | ||
46 | if (pop3 == NULL || pstream == NULL) | ||
47 | return MU_ERROR_INVALID_PARAMETER; | ||
48 | |||
49 | if (pop3->stream == NULL) | ||
50 | { | ||
51 | stream_t stream = NULL; | ||
52 | int status = stream_tcp_create (&stream); | ||
53 | if (status) | ||
54 | return status; | ||
55 | stream_buffer_create (&(pop3->stream), stream, 1024); | ||
56 | } | ||
57 | *pstream = pop3->stream; | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | /* Implementation of the stream for TOP and RETR. */ | 30 | /* Implementation of the stream for TOP and RETR. */ |
62 | static int p_add_ref __P ((stream_t)); | 31 | static int p_add_ref __P ((stream_t)); |
63 | static int p_release __P ((stream_t)); | 32 | static int p_release __P ((stream_t)); |
... | @@ -81,6 +50,12 @@ static int p_get_fd __P ((stream_t, int *)); | ... | @@ -81,6 +50,12 @@ static int p_get_fd __P ((stream_t, int *)); |
81 | static int p_get_flags __P ((stream_t, int *)); | 50 | static int p_get_flags __P ((stream_t, int *)); |
82 | static int p_get_state __P ((stream_t, enum stream_state *)); | 51 | static int p_get_state __P ((stream_t, enum stream_state *)); |
83 | 52 | ||
53 | static int p_is_readready __P ((stream_t, int timeout)); | ||
54 | static int p_is_writeready __P ((stream_t, int timeout)); | ||
55 | static int p_is_exceptionpending __P ((stream_t, int timeout)); | ||
56 | |||
57 | static int p_is_open __P ((stream_t)); | ||
58 | |||
84 | static struct _stream_vtable p_s_vtable = | 59 | static struct _stream_vtable p_s_vtable = |
85 | { | 60 | { |
86 | p_add_ref, | 61 | p_add_ref, |
... | @@ -104,6 +79,12 @@ static struct _stream_vtable p_s_vtable = | ... | @@ -104,6 +79,12 @@ static struct _stream_vtable p_s_vtable = |
104 | p_get_fd, | 79 | p_get_fd, |
105 | p_get_flags, | 80 | p_get_flags, |
106 | p_get_state, | 81 | p_get_state, |
82 | |||
83 | p_is_readready, | ||
84 | p_is_writeready, | ||
85 | p_is_exceptionpending, | ||
86 | |||
87 | p_is_open | ||
107 | }; | 88 | }; |
108 | 89 | ||
109 | int | 90 | int |
... | @@ -207,10 +188,9 @@ p_read (stream_t stream, void *buf, size_t buflen, size_t *pn) | ... | @@ -207,10 +188,9 @@ p_read (stream_t stream, void *buf, size_t buflen, size_t *pn) |
207 | size_t nread = 0; | 188 | size_t nread = 0; |
208 | 189 | ||
209 | /* The pop3_readline () function will always read one less to | 190 | /* The pop3_readline () function will always read one less to |
210 | be able to terminate the buffer, this will cause serious grief | 191 | be able to null terminate the buffer, this will cause |
211 | for stream_read() where it is legitimate to have a buffer of | 192 | serious grief for stream_read() where it is legitimate to |
212 | 1 char. So we must catch it here or change the behaviour of | 193 | have a buffer of 1 char. So we must catch it here. */ |
213 | XXX_readline. */ | ||
214 | if (buflen == 1) | 194 | if (buflen == 1) |
215 | { | 195 | { |
216 | char buffer[2]; | 196 | char buffer[2]; |
... | @@ -271,61 +251,89 @@ static int | ... | @@ -271,61 +251,89 @@ static int |
271 | p_write (stream_t stream, const void *buf, size_t buflen, size_t *pn) | 251 | p_write (stream_t stream, const void *buf, size_t buflen, size_t *pn) |
272 | { | 252 | { |
273 | struct p_stream *p_stream = (struct p_stream *)stream; | 253 | struct p_stream *p_stream = (struct p_stream *)stream; |
274 | return stream_write (p_stream->pop3->stream, buf, buflen, pn); | 254 | return stream_write (p_stream->pop3->carrier, buf, buflen, pn); |
275 | } | 255 | } |
276 | 256 | ||
277 | static int | 257 | static int |
278 | p_seek (stream_t stream, off_t offset, enum stream_whence whence) | 258 | p_seek (stream_t stream, off_t offset, enum stream_whence whence) |
279 | { | 259 | { |
280 | struct p_stream *p_stream = (struct p_stream *)stream; | 260 | struct p_stream *p_stream = (struct p_stream *)stream; |
281 | return stream_seek (p_stream->pop3->stream, offset, whence); | 261 | return stream_seek (p_stream->pop3->carrier, offset, whence); |
282 | } | 262 | } |
283 | 263 | ||
284 | static int | 264 | static int |
285 | p_tell (stream_t stream, off_t *offset) | 265 | p_tell (stream_t stream, off_t *offset) |
286 | { | 266 | { |
287 | struct p_stream *p_stream = (struct p_stream *)stream; | 267 | struct p_stream *p_stream = (struct p_stream *)stream; |
288 | return stream_tell (p_stream->pop3->stream, offset); | 268 | return stream_tell (p_stream->pop3->carrier, offset); |
289 | } | 269 | } |
290 | 270 | ||
291 | static int | 271 | static int |
292 | p_get_size (stream_t stream, off_t *size) | 272 | p_get_size (stream_t stream, off_t *size) |
293 | { | 273 | { |
294 | struct p_stream *p_stream = (struct p_stream *)stream; | 274 | struct p_stream *p_stream = (struct p_stream *)stream; |
295 | return stream_get_size (p_stream->pop3->stream, size); | 275 | return stream_get_size (p_stream->pop3->carrier, size); |
296 | } | 276 | } |
297 | 277 | ||
298 | static int | 278 | static int |
299 | p_truncate (stream_t stream, off_t size) | 279 | p_truncate (stream_t stream, off_t size) |
300 | { | 280 | { |
301 | struct p_stream *p_stream = (struct p_stream *)stream; | 281 | struct p_stream *p_stream = (struct p_stream *)stream; |
302 | return stream_truncate (p_stream->pop3->stream, size); | 282 | return stream_truncate (p_stream->pop3->carrier, size); |
303 | } | 283 | } |
304 | 284 | ||
305 | static int | 285 | static int |
306 | p_flush (stream_t stream) | 286 | p_flush (stream_t stream) |
307 | { | 287 | { |
308 | struct p_stream *p_stream = (struct p_stream *)stream; | 288 | struct p_stream *p_stream = (struct p_stream *)stream; |
309 | return stream_flush (p_stream->pop3->stream); | 289 | return stream_flush (p_stream->pop3->carrier); |
310 | } | 290 | } |
311 | 291 | ||
312 | static int | 292 | static int |
313 | p_get_fd (stream_t stream, int *fd) | 293 | p_get_fd (stream_t stream, int *fd) |
314 | { | 294 | { |
315 | struct p_stream *p_stream = (struct p_stream *)stream; | 295 | struct p_stream *p_stream = (struct p_stream *)stream; |
316 | return stream_get_fd (p_stream->pop3->stream, fd); | 296 | return stream_get_fd (p_stream->pop3->carrier, fd); |
317 | } | 297 | } |
318 | 298 | ||
319 | static int | 299 | static int |
320 | p_get_flags (stream_t stream, int *flags) | 300 | p_get_flags (stream_t stream, int *flags) |
321 | { | 301 | { |
322 | struct p_stream *p_stream = (struct p_stream *)stream; | 302 | struct p_stream *p_stream = (struct p_stream *)stream; |
323 | return stream_get_flags (p_stream->pop3->stream, flags); | 303 | return stream_get_flags (p_stream->pop3->carrier, flags); |
324 | } | 304 | } |
325 | 305 | ||
326 | static int | 306 | static int |
327 | p_get_state (stream_t stream, enum stream_state *state) | 307 | p_get_state (stream_t stream, enum stream_state *state) |
328 | { | 308 | { |
329 | struct p_stream *p_stream = (struct p_stream *)stream; | 309 | struct p_stream *p_stream = (struct p_stream *)stream; |
330 | return stream_get_state (p_stream->pop3->stream, state); | 310 | return stream_get_state (p_stream->pop3->carrier, state); |
311 | } | ||
312 | |||
313 | static int | ||
314 | p_is_readready (stream_t stream, int timeout) | ||
315 | { | ||
316 | struct p_stream *p_stream = (struct p_stream *)stream; | ||
317 | return stream_is_readready (p_stream->pop3->carrier, timeout); | ||
318 | } | ||
319 | |||
320 | static int | ||
321 | p_is_writeready (stream_t stream, int timeout) | ||
322 | { | ||
323 | struct p_stream *p_stream = (struct p_stream *)stream; | ||
324 | return stream_is_writeready (p_stream->pop3->carrier, timeout); | ||
325 | } | ||
326 | |||
327 | static int | ||
328 | p_is_exceptionpending (stream_t stream, int timeout) | ||
329 | { | ||
330 | struct p_stream *p_stream = (struct p_stream *)stream; | ||
331 | return stream_is_exceptionpending (p_stream->pop3->carrier, timeout); | ||
332 | } | ||
333 | |||
334 | static int | ||
335 | p_is_open (stream_t stream) | ||
336 | { | ||
337 | struct p_stream *p_stream = (struct p_stream *)stream; | ||
338 | return stream_is_open (p_stream->pop3->carrier); | ||
331 | } | 339 | } | ... | ... |
... | @@ -23,7 +23,7 @@ | ... | @@ -23,7 +23,7 @@ |
23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | 24 | ||
25 | int | 25 | int |
26 | pop3_set_timeout (pop3_t pop3, unsigned int timeout) | 26 | pop3_set_timeout (pop3_t pop3, int timeout) |
27 | { | 27 | { |
28 | /* Sanity checks. */ | 28 | /* Sanity checks. */ |
29 | if (pop3 == NULL) | 29 | if (pop3 == NULL) |
... | @@ -34,7 +34,7 @@ pop3_set_timeout (pop3_t pop3, unsigned int timeout) | ... | @@ -34,7 +34,7 @@ pop3_set_timeout (pop3_t pop3, unsigned int timeout) |
34 | } | 34 | } |
35 | 35 | ||
36 | int | 36 | int |
37 | pop3_get_timeout (pop3_t pop3, unsigned int *ptimeout) | 37 | pop3_get_timeout (pop3_t pop3, int *ptimeout) |
38 | { | 38 | { |
39 | /* Sanity checks. */ | 39 | /* Sanity checks. */ |
40 | if (pop3 == NULL || ptimeout == NULL) | 40 | if (pop3 == NULL || ptimeout == NULL) | ... | ... |
... | @@ -27,16 +27,18 @@ | ... | @@ -27,16 +27,18 @@ |
27 | 27 | ||
28 | #include <mailutils/sys/pop3.h> | 28 | #include <mailutils/sys/pop3.h> |
29 | 29 | ||
30 | static int | 30 | int |
31 | pop3_top0 (pop3_t pop3, unsigned msgno, size_t lines, stream_t *pstream) | 31 | pop3_top (pop3_t pop3, unsigned msgno, unsigned int lines, stream_t *pstream) |
32 | { | 32 | { |
33 | int status; | 33 | int status; |
34 | 34 | ||
35 | if (pop3 == NULL || msgno == 0 || pstream == NULL) | ||
36 | return MU_ERROR_INVALID_PARAMETER; | ||
37 | |||
38 | |||
35 | switch (pop3->state) | 39 | switch (pop3->state) |
36 | { | 40 | { |
37 | case POP3_NO_STATE: | 41 | case POP3_NO_STATE: |
38 | if (pstream == NULL) | ||
39 | return MU_ERROR_INVALID_PARAMETER; | ||
40 | status = pop3_writeline (pop3, "TOP %d %d\r\n", msgno, lines); | 42 | status = pop3_writeline (pop3, "TOP %d %d\r\n", msgno, lines); |
41 | POP3_CHECK_ERROR (pop3, status); | 43 | POP3_CHECK_ERROR (pop3, status); |
42 | pop3->state = POP3_TOP; | 44 | pop3->state = POP3_TOP; |
... | @@ -69,19 +71,3 @@ pop3_top0 (pop3_t pop3, unsigned msgno, size_t lines, stream_t *pstream) | ... | @@ -69,19 +71,3 @@ pop3_top0 (pop3_t pop3, unsigned msgno, size_t lines, stream_t *pstream) |
69 | 71 | ||
70 | return status; | 72 | return status; |
71 | } | 73 | } |
72 | |||
73 | int | ||
74 | pop3_top (pop3_t pop3, unsigned msgno, size_t lines, stream_t *pstream) | ||
75 | { | ||
76 | int status; | ||
77 | |||
78 | if (pop3 == NULL) | ||
79 | return MU_ERROR_INVALID_PARAMETER; | ||
80 | |||
81 | monitor_lock (pop3->lock); | ||
82 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
83 | status = pop3_top0 (pop3, msgno, lines, pstream); | ||
84 | monitor_unlock (pop3->lock); | ||
85 | monitor_cleanup_pop (0); | ||
86 | return status; | ||
87 | } | ... | ... |
... | @@ -28,16 +28,17 @@ | ... | @@ -28,16 +28,17 @@ |
28 | #include <stdlib.h> | 28 | #include <stdlib.h> |
29 | #include <mailutils/sys/pop3.h> | 29 | #include <mailutils/sys/pop3.h> |
30 | 30 | ||
31 | static int | 31 | int |
32 | pop3_uidl0 (pop3_t pop3, unsigned msgno, char **uidl) | 32 | pop3_uidl (pop3_t pop3, unsigned msgno, char **uidl) |
33 | { | 33 | { |
34 | int status; | 34 | int status; |
35 | 35 | ||
36 | if (pop3 == NULL || uidl == NULL) | ||
37 | return MU_ERROR_INVALID_PARAMETER; | ||
38 | |||
36 | switch (pop3->state) | 39 | switch (pop3->state) |
37 | { | 40 | { |
38 | case POP3_NO_STATE: | 41 | case POP3_NO_STATE: |
39 | if (uidl == NULL) | ||
40 | return MU_ERROR_INVALID_PARAMETER; | ||
41 | status = pop3_writeline (pop3, "UIDL %d\r\n", msgno); | 42 | status = pop3_writeline (pop3, "UIDL %d\r\n", msgno); |
42 | POP3_CHECK_ERROR (pop3, status); | 43 | POP3_CHECK_ERROR (pop3, status); |
43 | pop3->state = POP3_UIDL; | 44 | pop3->state = POP3_UIDL; |
... | @@ -98,19 +99,3 @@ pop3_uidl0 (pop3_t pop3, unsigned msgno, char **uidl) | ... | @@ -98,19 +99,3 @@ pop3_uidl0 (pop3_t pop3, unsigned msgno, char **uidl) |
98 | 99 | ||
99 | return status; | 100 | return status; |
100 | } | 101 | } |
101 | |||
102 | int | ||
103 | pop3_uidl (pop3_t pop3, unsigned msgno, char **uidl) | ||
104 | { | ||
105 | int status; | ||
106 | |||
107 | if (pop3 == NULL) | ||
108 | return MU_ERROR_INVALID_PARAMETER; | ||
109 | |||
110 | monitor_lock (pop3->lock); | ||
111 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
112 | status = pop3_uidl0 (pop3, msgno, uidl); | ||
113 | monitor_unlock (pop3->lock); | ||
114 | monitor_cleanup_pop (0); | ||
115 | return status; | ||
116 | } | ... | ... |
... | @@ -28,16 +28,17 @@ | ... | @@ -28,16 +28,17 @@ |
28 | #include <stdlib.h> | 28 | #include <stdlib.h> |
29 | #include <mailutils/sys/pop3.h> | 29 | #include <mailutils/sys/pop3.h> |
30 | 30 | ||
31 | static int | 31 | int |
32 | pop3_uidl_all0 (pop3_t pop3, iterator_t *piterator) | 32 | pop3_uidl_all (pop3_t pop3, iterator_t *piterator) |
33 | { | 33 | { |
34 | int status; | 34 | int status; |
35 | 35 | ||
36 | if (pop3 == NULL || piterator == NULL) | ||
37 | return MU_ERROR_INVALID_PARAMETER; | ||
38 | |||
36 | switch (pop3->state) | 39 | switch (pop3->state) |
37 | { | 40 | { |
38 | case POP3_NO_STATE: | 41 | case POP3_NO_STATE: |
39 | if (piterator == NULL) | ||
40 | return MU_ERROR_INVALID_PARAMETER; | ||
41 | status = pop3_writeline (pop3, "UIDL\r\n"); | 42 | status = pop3_writeline (pop3, "UIDL\r\n"); |
42 | POP3_CHECK_ERROR (pop3, status); | 43 | POP3_CHECK_ERROR (pop3, status); |
43 | pop3->state = POP3_UIDL; | 44 | pop3->state = POP3_UIDL; |
... | @@ -72,17 +73,30 @@ pop3_uidl_all0 (pop3_t pop3, iterator_t *piterator) | ... | @@ -72,17 +73,30 @@ pop3_uidl_all0 (pop3_t pop3, iterator_t *piterator) |
72 | } | 73 | } |
73 | 74 | ||
74 | int | 75 | int |
75 | pop3_uidl_all (pop3_t pop3, iterator_t *piterator) | 76 | pop3_uidl_current (iterator_t iterator, unsigned int *pno, char **puidl) |
76 | { | 77 | { |
77 | int status; | 78 | char *buf; |
78 | 79 | int status = iterator_current (iterator, (void *)&buf); | |
79 | if (pop3 == NULL) | 80 | if (status == 0) |
80 | return MU_ERROR_INVALID_PARAMETER; | 81 | { |
81 | 82 | char *space; | |
82 | monitor_lock (pop3->lock); | 83 | unsigned int msgno = 0; |
83 | monitor_cleanup_push (pop3_cleanup, pop3); | 84 | /* The format is: msgno uidlstring */ |
84 | status = pop3_uidl_all0 (pop3, piterator); | 85 | space = strchr (buf, ' '); |
85 | monitor_unlock (pop3->lock); | 86 | if (space) |
86 | monitor_cleanup_pop (0); | 87 | { |
88 | *space++ = '\0'; | ||
89 | msgno = strtoul (buf, NULL, 10); | ||
90 | } | ||
91 | if (space && space[strlen (space) - 1] == '\n') | ||
92 | space[strlen (space) - 1] = '\0'; | ||
93 | if (space == NULL) | ||
94 | space = (char *)""; | ||
95 | if (pno) | ||
96 | *pno = msgno; | ||
97 | if (puidl) | ||
98 | *puidl = strdup (space); | ||
99 | free (buf); | ||
100 | } | ||
87 | return status; | 101 | return status; |
88 | } | 102 | } | ... | ... |
... | @@ -27,16 +27,17 @@ | ... | @@ -27,16 +27,17 @@ |
27 | 27 | ||
28 | #include <mailutils/sys/pop3.h> | 28 | #include <mailutils/sys/pop3.h> |
29 | 29 | ||
30 | static int | 30 | int |
31 | pop3_user0 (pop3_t pop3, const char *user) | 31 | pop3_user (pop3_t pop3, const char *user) |
32 | { | 32 | { |
33 | int status; | 33 | int status; |
34 | 34 | ||
35 | if (pop3 == NULL || user == NULL) | ||
36 | return MU_ERROR_INVALID_PARAMETER; | ||
37 | |||
35 | switch (pop3->state) | 38 | switch (pop3->state) |
36 | { | 39 | { |
37 | case POP3_NO_STATE: | 40 | case POP3_NO_STATE: |
38 | if (user == NULL) | ||
39 | return MU_ERROR_INVALID_PARAMETER; | ||
40 | status = pop3_writeline (pop3, "USER %s\r\n", user); | 41 | status = pop3_writeline (pop3, "USER %s\r\n", user); |
41 | POP3_CHECK_ERROR (pop3, status); | 42 | POP3_CHECK_ERROR (pop3, status); |
42 | pop3->state = POP3_USER; | 43 | pop3->state = POP3_USER; |
... | @@ -65,19 +66,3 @@ pop3_user0 (pop3_t pop3, const char *user) | ... | @@ -65,19 +66,3 @@ pop3_user0 (pop3_t pop3, const char *user) |
65 | 66 | ||
66 | return status; | 67 | return status; |
67 | } | 68 | } |
68 | |||
69 | int | ||
70 | pop3_user (pop3_t pop3, const char *user) | ||
71 | { | ||
72 | int status; | ||
73 | |||
74 | if (pop3 == NULL) | ||
75 | return MU_ERROR_INVALID_PARAMETER; | ||
76 | |||
77 | monitor_lock (pop3->lock); | ||
78 | monitor_cleanup_push (pop3_cleanup, pop3); | ||
79 | status = pop3_user0 (pop3, user); | ||
80 | monitor_unlock (pop3->lock); | ||
81 | monitor_cleanup_pop (0); | ||
82 | return status; | ||
83 | } | ... | ... |
... | @@ -32,6 +32,7 @@ typedef struct { | ... | @@ -32,6 +32,7 @@ typedef struct { |
32 | 32 | ||
33 | /* The names of functions that actually do the manipulation. */ | 33 | /* The names of functions that actually do the manipulation. */ |
34 | int com_apop (char *); | 34 | int com_apop (char *); |
35 | int com_capa (char *); | ||
35 | int com_disconnect (char *); | 36 | int com_disconnect (char *); |
36 | int com_dele (char *); | 37 | int com_dele (char *); |
37 | int com_exit (char *); | 38 | int com_exit (char *); |
... | @@ -61,6 +62,7 @@ void sig_int (int); | ... | @@ -61,6 +62,7 @@ void sig_int (int); |
61 | 62 | ||
62 | COMMAND commands[] = { | 63 | COMMAND commands[] = { |
63 | { "apop", com_apop, "Authenticate with APOP: APOP user secret" }, | 64 | { "apop", com_apop, "Authenticate with APOP: APOP user secret" }, |
65 | { "capa", com_capa, "List capabilities: capa" }, | ||
64 | { "disconnect", com_disconnect, "Close connection: disconnect" }, | 66 | { "disconnect", com_disconnect, "Close connection: disconnect" }, |
65 | { "dele", com_dele, "Mark message: DELE msgno" }, | 67 | { "dele", com_dele, "Mark message: DELE msgno" }, |
66 | { "exit", com_exit, "exit program" }, | 68 | { "exit", com_exit, "exit program" }, |
... | @@ -333,6 +335,29 @@ com_apop (char *arg) | ... | @@ -333,6 +335,29 @@ com_apop (char *arg) |
333 | } | 335 | } |
334 | 336 | ||
335 | int | 337 | int |
338 | com_capa (char *arg) | ||
339 | { | ||
340 | iterator_t iterator; | ||
341 | int status = pop3_capa (pop3, &iterator); | ||
342 | (void)arg; | ||
343 | print_response (); | ||
344 | if (status == 0) | ||
345 | { | ||
346 | for (iterator_first (iterator); | ||
347 | !iterator_is_done (iterator); | ||
348 | iterator_next (iterator)) | ||
349 | { | ||
350 | char *capa = (char *)""; | ||
351 | iterator_current (iterator, &capa); | ||
352 | printf ("Capa: %s\n", capa); | ||
353 | free (capa); | ||
354 | } | ||
355 | iterator_destroy (iterator); | ||
356 | } | ||
357 | return status; | ||
358 | } | ||
359 | |||
360 | int | ||
336 | com_uidl (char *arg) | 361 | com_uidl (char *arg) |
337 | { | 362 | { |
338 | if (arg == NULL || *arg == '\0') | 363 | if (arg == NULL || *arg == '\0') |
... | @@ -346,10 +371,11 @@ com_uidl (char *arg) | ... | @@ -346,10 +371,11 @@ com_uidl (char *arg) |
346 | !iterator_is_done (uidl_iterator); | 371 | !iterator_is_done (uidl_iterator); |
347 | iterator_next (uidl_iterator)) | 372 | iterator_next (uidl_iterator)) |
348 | { | 373 | { |
349 | struct pop3_uidl_item *pl; | 374 | unsigned int msgno = 0; |
350 | iterator_current (uidl_iterator, (void *)&pl); | 375 | char *uidl = (char *)""; |
351 | printf ("Msg: %d UIDL: %s\n", pl->msgno, pl->uidl); | 376 | pop3_uidl_current (uidl_iterator, &msgno, &uidl); |
352 | free (pl); | 377 | printf ("Msg: %d UIDL: %s\n", msgno, uidl); |
378 | free (uidl); | ||
353 | } | 379 | } |
354 | iterator_destroy (uidl_iterator); | 380 | iterator_destroy (uidl_iterator); |
355 | } | 381 | } |
... | @@ -380,10 +406,10 @@ com_list (char *arg) | ... | @@ -380,10 +406,10 @@ com_list (char *arg) |
380 | !iterator_is_done (list_iterator); | 406 | !iterator_is_done (list_iterator); |
381 | iterator_next (list_iterator)) | 407 | iterator_next (list_iterator)) |
382 | { | 408 | { |
383 | struct pop3_list_item *pl; | 409 | unsigned int msgno = 0; |
384 | iterator_current (list_iterator, (void *)&pl); | 410 | size_t size = 0; |
385 | printf ("Msg: %d Size: %d\n", pl->msgno, pl->size); | 411 | pop3_list_current (list_iterator, &msgno, &size); |
386 | free (pl); | 412 | printf ("Msg: %d Size: %d\n", msgno, size); |
387 | } | 413 | } |
388 | iterator_destroy (list_iterator); | 414 | iterator_destroy (list_iterator); |
389 | } | 415 | } | ... | ... |
... | @@ -24,7 +24,7 @@ | ... | @@ -24,7 +24,7 @@ |
24 | #include <mailutils/sys/stream.h> | 24 | #include <mailutils/sys/stream.h> |
25 | 25 | ||
26 | int | 26 | int |
27 | (stream_add_ref) (stream_t stream) | 27 | stream_add_ref (stream_t stream) |
28 | { | 28 | { |
29 | if (stream == NULL || stream->vtable == NULL | 29 | if (stream == NULL || stream->vtable == NULL |
30 | || stream->vtable->add_ref == NULL) | 30 | || stream->vtable->add_ref == NULL) |
... | @@ -33,7 +33,7 @@ int | ... | @@ -33,7 +33,7 @@ int |
33 | } | 33 | } |
34 | 34 | ||
35 | int | 35 | int |
36 | (stream_release) (stream_t stream) | 36 | stream_release (stream_t stream) |
37 | { | 37 | { |
38 | if (stream == NULL || stream->vtable == NULL | 38 | if (stream == NULL || stream->vtable == NULL |
39 | || stream->vtable->release == NULL) | 39 | || stream->vtable->release == NULL) |
... | @@ -42,7 +42,7 @@ int | ... | @@ -42,7 +42,7 @@ int |
42 | } | 42 | } |
43 | 43 | ||
44 | int | 44 | int |
45 | (stream_destroy) (stream_t stream) | 45 | stream_destroy (stream_t stream) |
46 | { | 46 | { |
47 | if (stream == NULL || stream->vtable == NULL | 47 | if (stream == NULL || stream->vtable == NULL |
48 | || stream->vtable->destroy == NULL) | 48 | || stream->vtable->destroy == NULL) |
... | @@ -51,7 +51,7 @@ int | ... | @@ -51,7 +51,7 @@ int |
51 | } | 51 | } |
52 | 52 | ||
53 | int | 53 | int |
54 | (stream_open) (stream_t stream, const char *host, int port, int flag) | 54 | stream_open (stream_t stream, const char *host, int port, int flag) |
55 | { | 55 | { |
56 | if (stream == NULL || stream->vtable == NULL | 56 | if (stream == NULL || stream->vtable == NULL |
57 | || stream->vtable->open == NULL) | 57 | || stream->vtable->open == NULL) |
... | @@ -60,7 +60,7 @@ int | ... | @@ -60,7 +60,7 @@ int |
60 | } | 60 | } |
61 | 61 | ||
62 | int | 62 | int |
63 | (stream_close) (stream_t stream) | 63 | stream_close (stream_t stream) |
64 | { | 64 | { |
65 | if (stream == NULL || stream->vtable == NULL | 65 | if (stream == NULL || stream->vtable == NULL |
66 | || stream->vtable->close == NULL) | 66 | || stream->vtable->close == NULL) |
... | @@ -69,7 +69,7 @@ int | ... | @@ -69,7 +69,7 @@ int |
69 | } | 69 | } |
70 | 70 | ||
71 | int | 71 | int |
72 | (stream_read) (stream_t stream, void *buf, size_t buflen, size_t *n) | 72 | stream_read (stream_t stream, void *buf, size_t buflen, size_t *n) |
73 | { | 73 | { |
74 | if (stream == NULL || stream->vtable == NULL | 74 | if (stream == NULL || stream->vtable == NULL |
75 | || stream->vtable->read == NULL) | 75 | || stream->vtable->read == NULL) |
... | @@ -78,7 +78,7 @@ int | ... | @@ -78,7 +78,7 @@ int |
78 | } | 78 | } |
79 | 79 | ||
80 | int | 80 | int |
81 | (stream_readline) (stream_t stream, char *buf, size_t buflen, size_t *n) | 81 | stream_readline (stream_t stream, char *buf, size_t buflen, size_t *n) |
82 | { | 82 | { |
83 | if (stream == NULL || stream->vtable == NULL | 83 | if (stream == NULL || stream->vtable == NULL |
84 | || stream->vtable->readline == NULL) | 84 | || stream->vtable->readline == NULL) |
... | @@ -87,7 +87,7 @@ int | ... | @@ -87,7 +87,7 @@ int |
87 | } | 87 | } |
88 | 88 | ||
89 | int | 89 | int |
90 | (stream_write) (stream_t stream, const void *buf, size_t buflen, size_t *n) | 90 | stream_write (stream_t stream, const void *buf, size_t buflen, size_t *n) |
91 | { | 91 | { |
92 | if (stream == NULL || stream->vtable == NULL | 92 | if (stream == NULL || stream->vtable == NULL |
93 | || stream->vtable->write == NULL) | 93 | || stream->vtable->write == NULL) |
... | @@ -96,7 +96,7 @@ int | ... | @@ -96,7 +96,7 @@ int |
96 | } | 96 | } |
97 | 97 | ||
98 | int | 98 | int |
99 | (stream_seek) (stream_t stream, off_t off, enum stream_whence whence) | 99 | stream_seek (stream_t stream, off_t off, enum stream_whence whence) |
100 | { | 100 | { |
101 | if (stream == NULL || stream->vtable == NULL | 101 | if (stream == NULL || stream->vtable == NULL |
102 | || stream->vtable->seek == NULL) | 102 | || stream->vtable->seek == NULL) |
... | @@ -105,7 +105,7 @@ int | ... | @@ -105,7 +105,7 @@ int |
105 | } | 105 | } |
106 | 106 | ||
107 | int | 107 | int |
108 | (stream_tell) (stream_t stream, off_t *off) | 108 | stream_tell (stream_t stream, off_t *off) |
109 | { | 109 | { |
110 | if (stream == NULL || stream->vtable == NULL | 110 | if (stream == NULL || stream->vtable == NULL |
111 | || stream->vtable->tell == NULL) | 111 | || stream->vtable->tell == NULL) |
... | @@ -114,7 +114,7 @@ int | ... | @@ -114,7 +114,7 @@ int |
114 | } | 114 | } |
115 | 115 | ||
116 | int | 116 | int |
117 | (stream_get_size) (stream_t stream, off_t *off) | 117 | stream_get_size (stream_t stream, off_t *off) |
118 | { | 118 | { |
119 | if (stream == NULL || stream->vtable == NULL | 119 | if (stream == NULL || stream->vtable == NULL |
120 | || stream->vtable->get_size == NULL) | 120 | || stream->vtable->get_size == NULL) |
... | @@ -123,7 +123,7 @@ int | ... | @@ -123,7 +123,7 @@ int |
123 | } | 123 | } |
124 | 124 | ||
125 | int | 125 | int |
126 | (stream_truncate) (stream_t stream, off_t off) | 126 | stream_truncate (stream_t stream, off_t off) |
127 | { | 127 | { |
128 | if (stream == NULL || stream->vtable == NULL | 128 | if (stream == NULL || stream->vtable == NULL |
129 | || stream->vtable->truncate == NULL) | 129 | || stream->vtable->truncate == NULL) |
... | @@ -132,7 +132,7 @@ int | ... | @@ -132,7 +132,7 @@ int |
132 | } | 132 | } |
133 | 133 | ||
134 | int | 134 | int |
135 | (stream_flush) (stream_t stream) | 135 | stream_flush (stream_t stream) |
136 | { | 136 | { |
137 | if (stream == NULL || stream->vtable == NULL | 137 | if (stream == NULL || stream->vtable == NULL |
138 | || stream->vtable->flush == NULL) | 138 | || stream->vtable->flush == NULL) |
... | @@ -141,7 +141,7 @@ int | ... | @@ -141,7 +141,7 @@ int |
141 | } | 141 | } |
142 | 142 | ||
143 | int | 143 | int |
144 | (stream_get_fd) (stream_t stream, int *fd) | 144 | stream_get_fd (stream_t stream, int *fd) |
145 | { | 145 | { |
146 | if (stream == NULL || stream->vtable == NULL | 146 | if (stream == NULL || stream->vtable == NULL |
147 | || stream->vtable->get_fd == NULL) | 147 | || stream->vtable->get_fd == NULL) |
... | @@ -150,7 +150,7 @@ int | ... | @@ -150,7 +150,7 @@ int |
150 | } | 150 | } |
151 | 151 | ||
152 | int | 152 | int |
153 | (stream_get_flags) (stream_t stream, int *flags) | 153 | stream_get_flags (stream_t stream, int *flags) |
154 | { | 154 | { |
155 | if (stream == NULL || stream->vtable == NULL | 155 | if (stream == NULL || stream->vtable == NULL |
156 | || stream->vtable->get_flags == NULL) | 156 | || stream->vtable->get_flags == NULL) |
... | @@ -158,11 +158,48 @@ int | ... | @@ -158,11 +158,48 @@ int |
158 | return stream->vtable->get_flags (stream, flags); | 158 | return stream->vtable->get_flags (stream, flags); |
159 | } | 159 | } |
160 | 160 | ||
161 | |||
161 | int | 162 | int |
162 | (stream_get_state) (stream_t stream, enum stream_state *state) | 163 | stream_get_state (stream_t stream, enum stream_state *state) |
163 | { | 164 | { |
164 | if (stream == NULL || stream->vtable == NULL | 165 | if (stream == NULL || stream->vtable == NULL |
165 | || stream->vtable->get_state == NULL) | 166 | || stream->vtable->get_state == NULL) |
166 | return MU_ERROR_NOT_SUPPORTED; | 167 | return MU_ERROR_NOT_SUPPORTED; |
167 | return stream->vtable->get_state (stream, state); | 168 | return stream->vtable->get_state (stream, state); |
168 | } | 169 | } |
170 | |||
171 | int | ||
172 | stream_is_readready (stream_t stream, int timeout) | ||
173 | { | ||
174 | if (stream == NULL || stream->vtable == NULL | ||
175 | || stream->vtable->is_readready == NULL) | ||
176 | return MU_ERROR_NOT_SUPPORTED; | ||
177 | return stream->vtable->is_readready (stream, timeout); | ||
178 | } | ||
179 | |||
180 | int | ||
181 | stream_is_writeready (stream_t stream, int timeout) | ||
182 | { | ||
183 | if (stream == NULL || stream->vtable == NULL | ||
184 | || stream->vtable->is_writeready == NULL) | ||
185 | return MU_ERROR_NOT_SUPPORTED; | ||
186 | return stream->vtable->is_writeready (stream, timeout); | ||
187 | } | ||
188 | |||
189 | int | ||
190 | stream_is_exceptionpending (stream_t stream, int timeout) | ||
191 | { | ||
192 | if (stream == NULL || stream->vtable == NULL | ||
193 | || stream->vtable->is_exceptionpending == NULL) | ||
194 | return MU_ERROR_NOT_SUPPORTED; | ||
195 | return stream->vtable->is_exceptionpending (stream, timeout); | ||
196 | } | ||
197 | |||
198 | int | ||
199 | stream_is_open (stream_t stream) | ||
200 | { | ||
201 | if (stream == NULL || stream->vtable == NULL | ||
202 | || stream->vtable->is_open == NULL) | ||
203 | return MU_ERROR_NOT_SUPPORTED; | ||
204 | return stream->vtable->is_open (stream); | ||
205 | } | ... | ... |
... | @@ -31,6 +31,9 @@ | ... | @@ -31,6 +31,9 @@ |
31 | #include <netinet/in.h> | 31 | #include <netinet/in.h> |
32 | #include <arpa/inet.h> | 32 | #include <arpa/inet.h> |
33 | #include <unistd.h> | 33 | #include <unistd.h> |
34 | #include <sys/time.h> | ||
35 | #include <sys/types.h> | ||
36 | #include <unistd.h> | ||
34 | 37 | ||
35 | #include <mailutils/sys/tcpstream.h> | 38 | #include <mailutils/sys/tcpstream.h> |
36 | #include <mailutils/error.h> | 39 | #include <mailutils/error.h> |
... | @@ -354,6 +357,67 @@ _tcp_get_state (stream_t stream, enum stream_state *state) | ... | @@ -354,6 +357,67 @@ _tcp_get_state (stream_t stream, enum stream_state *state) |
354 | return 0; | 357 | return 0; |
355 | } | 358 | } |
356 | 359 | ||
360 | static int | ||
361 | _tcp_is_readready (stream_t stream, int timeout) | ||
362 | { | ||
363 | struct _tcp_instance *tcp = (struct _tcp_instance *)stream; | ||
364 | int ready; | ||
365 | struct timeval tv; | ||
366 | fd_set fds; | ||
367 | |||
368 | FD_ZERO (&fds); | ||
369 | FD_SET (tcp->fd, &fds); | ||
370 | |||
371 | tv.tv_sec = timeout / 100; | ||
372 | tv.tv_usec = (timeout % 1000) * 1000; | ||
373 | |||
374 | ready = select (tcp->fd + 1, &fds, NULL, NULL, (timeout == -1) ? NULL: &tv); | ||
375 | return (ready == -1) ? 0 : 1; | ||
376 | } | ||
377 | |||
378 | static int | ||
379 | _tcp_is_writeready (stream_t stream, int timeout) | ||
380 | { | ||
381 | struct _tcp_instance *tcp = (struct _tcp_instance *)stream; | ||
382 | int ready; | ||
383 | struct timeval tv; | ||
384 | fd_set fds; | ||
385 | |||
386 | FD_ZERO (&fds); | ||
387 | FD_SET (tcp->fd, &fds); | ||
388 | |||
389 | tv.tv_sec = timeout / 100; | ||
390 | tv.tv_usec = (timeout % 1000) * 1000; | ||
391 | |||
392 | ready = select (tcp->fd + 1, NULL, &fds, NULL, (timeout == -1) ? NULL: &tv); | ||
393 | return (ready == -1) ? 0 : 1; | ||
394 | } | ||
395 | |||
396 | static int | ||
397 | _tcp_is_exceptionpending (stream_t stream, int timeout) | ||
398 | { | ||
399 | struct _tcp_instance *tcp = (struct _tcp_instance *)stream; | ||
400 | int ready; | ||
401 | struct timeval tv; | ||
402 | fd_set fds; | ||
403 | |||
404 | FD_ZERO (&fds); | ||
405 | FD_SET (tcp->fd, &fds); | ||
406 | |||
407 | tv.tv_sec = timeout / 100; | ||
408 | tv.tv_usec = (timeout % 1000) * 1000; | ||
409 | |||
410 | ready = select (tcp->fd + 1, NULL, NULL, &fds, (timeout == -1) ? NULL: &tv); | ||
411 | return (ready == -1) ? 0 : 1; | ||
412 | } | ||
413 | |||
414 | static int | ||
415 | _tcp_is_open (stream_t stream) | ||
416 | { | ||
417 | struct _tcp_instance *tcp = (struct _tcp_instance *)stream; | ||
418 | return tcp->fd >= 0; | ||
419 | } | ||
420 | |||
357 | static struct _stream_vtable _tcp_vtable = | 421 | static struct _stream_vtable _tcp_vtable = |
358 | { | 422 | { |
359 | _tcp_add_ref, | 423 | _tcp_add_ref, |
... | @@ -376,7 +440,13 @@ static struct _stream_vtable _tcp_vtable = | ... | @@ -376,7 +440,13 @@ static struct _stream_vtable _tcp_vtable = |
376 | 440 | ||
377 | _tcp_get_fd, | 441 | _tcp_get_fd, |
378 | _tcp_get_flags, | 442 | _tcp_get_flags, |
379 | _tcp_get_state | 443 | _tcp_get_state, |
444 | |||
445 | _tcp_is_readready, | ||
446 | _tcp_is_writeready, | ||
447 | _tcp_is_exceptionpending, | ||
448 | |||
449 | _tcp_is_open | ||
380 | }; | 450 | }; |
381 | 451 | ||
382 | int | 452 | int | ... | ... |
-
Please register or sign in to post a comment