Commit d22b2199 d22b2199ab813bf994afc2dbe8e033ffcc01d045 by Sergey Poznyakoff

Minor change in stream API. Improve POP3 client interface.

* include/mailutils/sys/stream.h (_MU_STR_EVENT_SET)
(_MU_STR_EVENT_CLR): New defines.
(_mu_stream) <event_cb, event_mask>: New members.
* mailbox/stream.c (_stream_setflag, _stream_clrflag): New static
functions.
All functions use these instead of setting/clearing flags directly.
(_mu_stream_cleareof, _mu_stream_seteof): New extern functions.
(_stream_cleareof): Remove define, use _mu_stream_cleareof instead.
(_stream_fill_buffer): Set EOF marker when end of stream is reached.

* mailbox/fltstream.c (filter_read): Call _mu_stream_seteof to set
EOF flag.

* include/mailutils/pop3.h: Get rid of the superfluous "extern" in
front of function prototypes.
Add new prototypes.
Remove extra whitespace.

* libproto/pop/pop3_capatst.c: New file.
* libproto/pop/pop3_list_cmd.c: New file.
* libproto/pop/pop3_listas.c: New file.
* libproto/pop/pop3_rdlist.c: New file.
* libproto/pop/pop3_uidl_cmd.c: New file.
* libproto/pop/pop3_uidlas.c: New file.
* libproto/pop/Makefile.am: Add new files.
* libproto/pop/pop3_capa.c (_mu_pop3_fill_list): Remove.
Use mu_pop3_read_list instead.
(capa_comp): New comparator for capa lists.
* libproto/pop/pop3_list.c (mu_pop3_list): Fix format specifier.
* libproto/pop/pop3_lista.c (mu_pop3_list_all): Rewrite.
* libproto/pop/pop3_retr.c (mu_pop3_retr) <MU_POP3_RETR_RX>: do not
reset state, this is done by the EOF event callback.
* libproto/pop/pop3_top.c (mu_pop3_top) <MU_POP3_TOP_RX>: Likewise.
* libproto/pop/pop3_stream.c (pop3_decode_state): New state pds_char.
Change semantics of pds_init.
(newstate, _pop3_decoder): Handle .\r\n in the initial state.
(_pop3_event_cb): New event callback.
(mu_pop3_filter_create): Set event callback on the filter stream.
* libproto/pop/pop3_uidla.c (mu_pop3_uidl_all): Rewrite.

* examples/Makefile.am (pop3client_CPPFLAGS): Add MU_APP_COMMON_INCLUDES.
* examples/pop3client.c: Rewrite command parser.
1 parent b94a6d3c
...@@ -111,6 +111,7 @@ sfrom_LDADD =\ ...@@ -111,6 +111,7 @@ sfrom_LDADD =\
111 @MU_AUTHLIBS@\ 111 @MU_AUTHLIBS@\
112 ${MU_LIB_MAILUTILS} 112 ${MU_LIB_MAILUTILS}
113 113
114 pop3client_CPPFLAGS = @MU_APP_COMMON_INCLUDES@
114 pop3client_LDADD = \ 115 pop3client_LDADD = \
115 ../lib/libmuaux.la\ 116 ../lib/libmuaux.la\
116 ${MU_LIB_POP}\ 117 ${MU_LIB_POP}\
......
...@@ -32,87 +32,99 @@ struct _mu_pop3; ...@@ -32,87 +32,99 @@ struct _mu_pop3;
32 typedef struct _mu_pop3 *mu_pop3_t; 32 typedef struct _mu_pop3 *mu_pop3_t;
33 33
34 #define MU_POP3_DEFAULT_PORT 110 34 #define MU_POP3_DEFAULT_PORT 110
35 #define MU_POP3_DEFAULT_SSL_PORT 995
35 36
36 extern int mu_pop3_create (mu_pop3_t *pop3); 37 int mu_pop3_create (mu_pop3_t *pop3);
37 extern void mu_pop3_destroy (mu_pop3_t *pop3); 38 void mu_pop3_destroy (mu_pop3_t *pop3);
38 39
39 extern int mu_pop3_set_carrier (mu_pop3_t pop3, mu_stream_t carrier); 40 int mu_pop3_set_carrier (mu_pop3_t pop3, mu_stream_t carrier);
40 extern int mu_pop3_get_carrier (mu_pop3_t pop3, mu_stream_t *pcarrier); 41 int mu_pop3_get_carrier (mu_pop3_t pop3, mu_stream_t *pcarrier);
41 42
42 extern int mu_pop3_connect (mu_pop3_t pop3); 43 int mu_pop3_connect (mu_pop3_t pop3);
43 extern int mu_pop3_disconnect (mu_pop3_t pop3); 44 int mu_pop3_disconnect (mu_pop3_t pop3);
44 45
45 extern int mu_pop3_set_timeout (mu_pop3_t pop3, int timeout); 46 int mu_pop3_set_timeout (mu_pop3_t pop3, int timeout);
46 extern int mu_pop3_get_timeout (mu_pop3_t pop3, int *timeout); 47 int mu_pop3_get_timeout (mu_pop3_t pop3, int *timeout);
47 48
48 #define MU_POP3_TRACE_CLR 0 49 #define MU_POP3_TRACE_CLR 0
49 #define MU_POP3_TRACE_SET 1 50 #define MU_POP3_TRACE_SET 1
50 #define MU_POP3_TRACE_QRY 2 51 #define MU_POP3_TRACE_QRY 2
51 extern int mu_pop3_trace (mu_pop3_t pop3, int op); 52 int mu_pop3_trace (mu_pop3_t pop3, int op);
52 53
53 extern int mu_pop3_apop (mu_pop3_t pop3, const char *name, const char *digest); 54 int mu_pop3_apop (mu_pop3_t pop3, const char *name, const char *digest);
54 55
55 extern int mu_pop3_stls (mu_pop3_t pop3); 56 int mu_pop3_stls (mu_pop3_t pop3);
56 57
57 /* It is the responsability of the caller to call mu_iterator_destroy() when 58 /* It is the responsability of the caller to call mu_iterator_destroy() when
58 done with the iterator. The items returned by the iterator are of type 59 done with the iterator. The items returned by the iterator are of type
59 "const char *", no processing is done on the item except the removal of 60 "const char *", no processing is done on the item except the removal of
60 the trailing newline. */ 61 the trailing newline. */
61 extern int mu_pop3_capa (mu_pop3_t pop3, int reread, 62 int mu_pop3_capa (mu_pop3_t pop3, int reread, mu_iterator_t *piter);
62 mu_iterator_t *piter); 63 int pop3_capa_test (mu_pop3_t pop3, const char *name, const char **pret);
63 64
64 extern int mu_pop3_dele (mu_pop3_t pop3, unsigned int mesgno); 65 int mu_pop3_dele (mu_pop3_t pop3, unsigned int mesgno);
65 66
66 extern int mu_pop3_list (mu_pop3_t pop3, unsigned int mesgno, size_t *mesg_octet); 67 int mu_pop3_list (mu_pop3_t pop3, unsigned int mesgno, size_t *mesg_octet);
67 68
68 /* An iterator is return with the multi-line answer. It is the responsability 69 /* Send the LIST command and prepare pop3 for receiving a multiline answer.
69 of the caller to call mu_iterator_destroy() to dispose of the iterator. */ 70 The caller is expected to obtain a stream via mu_pop3_stream_create,
70 extern int mu_pop3_list_all (mu_pop3_t pop3, mu_iterator_t *piterator); 71 or an iterator via mu_pop3_iterator_create and read data from them.
71 72
72 extern int mu_pop3_noop (mu_pop3_t pop3); 73 This function is not intended for use by a casual user, better use
74 mu_pop3_list_all or mu_pop3_list_all_stream. */
75 int mu_pop3_list_cmd (mu_pop3_t pop3);
76 int mu_pop3_list_all (mu_pop3_t pop3, mu_iterator_t *pitr);
77 int mu_pop3_list_all_stream (mu_pop3_t pop3, mu_stream_t *pstream);
73 78
74 extern int mu_pop3_pass (mu_pop3_t pop3, const char *pass); 79 int mu_pop3_noop (mu_pop3_t pop3);
75 80
76 extern int mu_pop3_quit (mu_pop3_t pop3); 81 int mu_pop3_pass (mu_pop3_t pop3, const char *pass);
82
83 int mu_pop3_quit (mu_pop3_t pop3);
77 84
78 /* A stream is returned with the multi-line answer. It is the responsability 85 /* A stream is returned with the multi-line answer. It is the responsability
79 of the caller to call mu_stream_destroy() to dipose of the stream. */ 86 of the caller to call mu_stream_destroy() to dipose of the stream. */
80 extern int mu_pop3_retr (mu_pop3_t pop3, unsigned int mesgno, 87 int mu_pop3_retr (mu_pop3_t pop3, unsigned int mesgno,
81 mu_stream_t *pstream); 88 mu_stream_t *pstream);
82 89
83 extern int mu_pop3_rset (mu_pop3_t pop3); 90 int mu_pop3_rset (mu_pop3_t pop3);
84 91
85 extern int mu_pop3_stat (mu_pop3_t pop3, unsigned int *count, 92 int mu_pop3_stat (mu_pop3_t pop3, unsigned int *count, size_t *octets);
86 size_t *octets);
87 93
88 /* A stream is returned with the multi-line answer. It is the responsability 94 /* A stream is returned with the multi-line answer. It is the responsability
89 of the caller to call mu_stream_destroy() to dipose of the stream. */ 95 of the caller to call mu_stream_destroy() to dipose of the stream. */
90 extern int mu_pop3_top (mu_pop3_t pop3, unsigned int mesgno, 96 int mu_pop3_top (mu_pop3_t pop3, unsigned int mesgno,
91 unsigned int lines, mu_stream_t *pstream); 97 unsigned int lines, mu_stream_t *pstream);
92 98
93 /* The uidl is malloc'ed and returned in puidl; it is the responsability of 99 /* The uidl is malloc'ed and returned in puidl; it is the responsability of
94 the caller to free() the uild when done. */ 100 the caller to free() the uild when done. */
95 extern int mu_pop3_uidl (mu_pop3_t pop3, unsigned int mesgno, 101 int mu_pop3_uidl (mu_pop3_t pop3, unsigned int mesgno, char **puidl);
96 char **puidl);
97 /* An iterator is returned with the multi-line answer. It is the
98 responsability of the caller to call mu_iterator_destroy() to dispose of
99 the iterator. */
100 extern int mu_pop3_uidl_all (mu_pop3_t pop3, mu_iterator_t *piterator);
101 102
102 extern int mu_pop3_user (mu_pop3_t pop3, const char *user); 103 /* Send the UIDL command and prepare pop3 for receiving a multiline answer.
104 The caller is expected to obtain a stream via mu_pop3_stream_create,
105 or an iterator via mu_pop3_iterator_create and read data from them.
103 106
107 This function is not intended for use by a casual user, better use
108 mu_pop3_uidl_all or mu_pop3_uidl_all_stream. */
109 int mu_pop3_uidl_all_cmd (mu_pop3_t pop3);
110 int mu_pop3_uidl_all (mu_pop3_t pop3, mu_iterator_t *piterator);
111 int mu_pop3_uidl_all_stream (mu_pop3_t pop3, mu_stream_t *pstream);
104 112
113 int mu_pop3_user (mu_pop3_t pop3, const char *user);
105 114
106 /* Returns the last command acknowledge. If the server supports RESP-CODE, 115 /* Returns the last command acknowledge. If the server supports RESP-CODE,
107 the message could be retrieved, but it is up to the caller to do the 116 the message could be retrieved, but it is up to the caller to do the
108 parsing. */ 117 parsing. */
109 extern int mu_pop3_response (mu_pop3_t pop3, size_t *nread); 118 int mu_pop3_response (mu_pop3_t pop3, size_t *nread);
110 119
111 extern int mu_pop3_writeline (mu_pop3_t pop3, const char *format, ...) 120 int mu_pop3_writeline (mu_pop3_t pop3, const char *format, ...)
112 MU_PRINTFLIKE(2,3); 121 MU_PRINTFLIKE(2,3);
113 122
114 extern int mu_pop3_sendline (mu_pop3_t pop3, const char *line); 123 int mu_pop3_sendline (mu_pop3_t pop3, const char *line);
115 extern int mu_pop3_getline (mu_pop3_t pop3); 124 int mu_pop3_getline (mu_pop3_t pop3);
125 int mu_pop3_read_list (mu_pop3_t pop3, mu_list_t list);
126 int mu_pop3_stream_to_list (mu_pop3_t pop3, mu_stream_t stream,
127 mu_list_t list);
116 128
117 #ifdef __cplusplus 129 #ifdef __cplusplus
118 } 130 }
......
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
24 24
25 #define _MU_STR_INTERN_MASK 0xf000 25 #define _MU_STR_INTERN_MASK 0xf000
26 26
27 #define _MU_STR_EVENT_SET 1
28 #define _MU_STR_EVENT_CLR 2
29
27 struct _mu_stream 30 struct _mu_stream
28 { 31 {
29 int ref_count; 32 int ref_count;
...@@ -54,6 +57,9 @@ struct _mu_stream ...@@ -54,6 +57,9 @@ struct _mu_stream
54 int (*truncate) (struct _mu_stream *, mu_off_t); 57 int (*truncate) (struct _mu_stream *, mu_off_t);
55 int (*shutdown) (struct _mu_stream *, int); 58 int (*shutdown) (struct _mu_stream *, int);
56 59
60 void (*event_cb) (struct _mu_stream *, int, int);
61 int event_mask;
62
57 const char *(*error_string) (struct _mu_stream *, int); 63 const char *(*error_string) (struct _mu_stream *, int);
58 64
59 }; 65 };
...@@ -65,6 +71,9 @@ int mu_stream_write_unbuffered (mu_stream_t stream, ...@@ -65,6 +71,9 @@ int mu_stream_write_unbuffered (mu_stream_t stream,
65 const void *buf, size_t size, 71 const void *buf, size_t size,
66 int full_write, size_t *pnwritten); 72 int full_write, size_t *pnwritten);
67 73
74 void _mu_stream_cleareof (mu_stream_t str);
75 void _mu_stream_seteof (mu_stream_t str);
76
68 #define _MU_SWAP_FIRST_ONLY 0x01 77 #define _MU_SWAP_FIRST_ONLY 0x01
69 #define _MU_SWAP_IOCTL_MUST_SUCCEED 0x02 78 #define _MU_SWAP_IOCTL_MUST_SUCCEED 0x02
70 79
......
...@@ -24,13 +24,14 @@ lib_LTLIBRARIES = libmu_pop.la ...@@ -24,13 +24,14 @@ lib_LTLIBRARIES = libmu_pop.la
24 libmu_pop_la_LDFLAGS=-version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@ 24 libmu_pop_la_LDFLAGS=-version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@
25 libmu_pop_la_LIBADD = ${MU_LIB_AUTH} ${MU_LIB_MAILUTILS} @INTLLIBS@ 25 libmu_pop_la_LIBADD = ${MU_LIB_AUTH} ${MU_LIB_MAILUTILS} @INTLLIBS@
26 26
27 # folder.c\ 27 # folder.c\
28 # mbox.c\ 28 # url.c\
29 # url.c 29 # mbox.c
30 libmu_pop_la_SOURCES = \ 30 libmu_pop_la_SOURCES = \
31 \ 31 \
32 pop3_apop.c \ 32 pop3_apop.c \
33 pop3_capa.c \ 33 pop3_capa.c \
34 pop3_capatst.c \
34 pop3_carrier.c \ 35 pop3_carrier.c \
35 pop3_connect.c \ 36 pop3_connect.c \
36 pop3_create.c \ 37 pop3_create.c \
...@@ -39,10 +40,13 @@ libmu_pop_la_SOURCES = \ ...@@ -39,10 +40,13 @@ libmu_pop_la_SOURCES = \
39 pop3_disconnect.c \ 40 pop3_disconnect.c \
40 pop3_iterator.c \ 41 pop3_iterator.c \
41 pop3_lista.c \ 42 pop3_lista.c \
43 pop3_listas.c \
42 pop3_list.c \ 44 pop3_list.c \
45 pop3_list_cmd.c \
43 pop3_noop.c \ 46 pop3_noop.c \
44 pop3_pass.c \ 47 pop3_pass.c \
45 pop3_quit.c \ 48 pop3_quit.c \
49 pop3_rdlist.c \
46 pop3_readline.c \ 50 pop3_readline.c \
47 pop3_response.c \ 51 pop3_response.c \
48 pop3_retr.c \ 52 pop3_retr.c \
...@@ -54,7 +58,9 @@ libmu_pop_la_SOURCES = \ ...@@ -54,7 +58,9 @@ libmu_pop_la_SOURCES = \
54 pop3_timeout.c \ 58 pop3_timeout.c \
55 pop3_top.c \ 59 pop3_top.c \
56 pop3_trace.c \ 60 pop3_trace.c \
61 pop3_uidl_cmd.c \
57 pop3_uidla.c \ 62 pop3_uidla.c \
63 pop3_uidlas.c \
58 pop3_uidl.c \ 64 pop3_uidl.c \
59 pop3_user.c 65 pop3_user.c
60 66
......
...@@ -33,36 +33,18 @@ ...@@ -33,36 +33,18 @@
33 #include <mailutils/sys/pop3.h> 33 #include <mailutils/sys/pop3.h>
34 34
35 static int 35 static int
36 string_comp (const void *item, const void *value) 36 capa_comp (const void *item, const void *value)
37 { 37 {
38 return strcmp (item, value); 38 const char *capa = item;
39 } 39 const char *needle = value;
40 40 for (; *needle; capa++, needle++)
41 int
42 _mu_pop3_fill_list (mu_pop3_t pop3, mu_list_t list)
43 {
44 mu_stream_t stream;
45 size_t n;
46 int status = mu_pop3_stream_create (pop3, &stream);
47 if (status)
48 return status;
49
50 while (mu_stream_getline (stream, &pop3->rdbuf, &pop3->rdsize, &n) == 0
51 && n > 0)
52 { 41 {
53 char *np = strdup (pop3->rdbuf); 42 if (!*capa)
54 if (!np) 43 return 1;
55 { 44 if (mu_tolower (*capa) != mu_tolower (*needle))
56 status = ENOMEM; 45 return 1;
57 break;
58 }
59 mu_rtrim_class (np, MU_CTYPE_SPACE);
60 status = mu_list_append (list, np);
61 if (status)
62 break;
63 } 46 }
64 mu_stream_destroy (&stream); 47 return !(*capa == 0 || mu_isspace (*capa));
65 return status;
66 } 48 }
67 49
68 /* 50 /*
...@@ -91,7 +73,7 @@ mu_pop3_capa (mu_pop3_t pop3, int reread, mu_iterator_t *piter) ...@@ -91,7 +73,7 @@ mu_pop3_capa (mu_pop3_t pop3, int reread, mu_iterator_t *piter)
91 status = mu_list_create (&pop3->capa); 73 status = mu_list_create (&pop3->capa);
92 if (status) 74 if (status)
93 return status; 75 return status;
94 mu_list_set_comparator (pop3->capa, string_comp); 76 mu_list_set_comparator (pop3->capa, capa_comp);
95 mu_list_set_destroy_item (pop3->capa, mu_list_free_item); 77 mu_list_set_destroy_item (pop3->capa, mu_list_free_item);
96 78
97 switch (pop3->state) 79 switch (pop3->state)
...@@ -109,7 +91,7 @@ mu_pop3_capa (mu_pop3_t pop3, int reread, mu_iterator_t *piter) ...@@ -109,7 +91,7 @@ mu_pop3_capa (mu_pop3_t pop3, int reread, mu_iterator_t *piter)
109 pop3->state = MU_POP3_CAPA_RX; 91 pop3->state = MU_POP3_CAPA_RX;
110 92
111 case MU_POP3_CAPA_RX: 93 case MU_POP3_CAPA_RX:
112 status = _mu_pop3_fill_list (pop3, pop3->capa); 94 status = mu_pop3_read_list (pop3, pop3->capa);
113 MU_POP3_CHECK_ERROR (pop3, status); 95 MU_POP3_CHECK_ERROR (pop3, status);
114 if (piter) 96 if (piter)
115 status = mu_list_get_iterator (pop3->capa, piter); 97 status = mu_list_get_iterator (pop3->capa, piter);
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2003, 2004, 2005, 2007, 2010 Free Software Foundation,
3 Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General
16 Public License along with this library; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301 USA */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include <stdlib.h>
25 #include <mailutils/list.h>
26 #include <mailutils/sys/pop3.h>
27
28 int
29 pop3_capa_test (mu_pop3_t pop3, const char *name, const char **pret)
30 {
31 int rc;
32
33 rc = mu_pop3_capa (pop3, 0, NULL);
34 if (rc)
35 return rc;
36 return mu_list_locate (pop3->capa, (void*) name, (void**)pret);
37 }
...@@ -40,7 +40,7 @@ mu_pop3_list (mu_pop3_t pop3, unsigned int msgno, size_t *psize) ...@@ -40,7 +40,7 @@ mu_pop3_list (mu_pop3_t pop3, unsigned int msgno, size_t *psize)
40 switch (pop3->state) 40 switch (pop3->state)
41 { 41 {
42 case MU_POP3_NO_STATE: 42 case MU_POP3_NO_STATE:
43 status = mu_pop3_writeline (pop3, "LIST %d\r\n", msgno); 43 status = mu_pop3_writeline (pop3, "LIST %u\r\n", msgno);
44 MU_POP3_CHECK_ERROR (pop3, status); 44 MU_POP3_CHECK_ERROR (pop3, status);
45 MU_POP3_FCLR (pop3, MU_POP3_ACK); 45 MU_POP3_FCLR (pop3, MU_POP3_ACK);
46 pop3->state = MU_POP3_LIST; 46 pop3->state = MU_POP3_LIST;
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2004, 2007, 2010 Free Software
3 Foundation, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General
16 Public License along with this library; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301 USA */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include <stdlib.h>
25 #include <mailutils/sys/pop3.h>
26
27 int
28 mu_pop3_list_cmd (mu_pop3_t pop3)
29 {
30 int status = 0;
31
32 if (pop3 == NULL)
33 return EINVAL;
34
35 switch (pop3->state)
36 {
37 case MU_POP3_NO_STATE:
38 status = mu_pop3_writeline (pop3, "LIST\r\n");
39 MU_POP3_CHECK_ERROR (pop3, status);
40 MU_POP3_FCLR (pop3, MU_POP3_ACK);
41 pop3->state = MU_POP3_LIST;
42
43 case MU_POP3_LIST:
44 status = mu_pop3_response (pop3, NULL);
45 MU_POP3_CHECK_EAGAIN (pop3, status);
46 MU_POP3_CHECK_OK (pop3);
47 pop3->state = MU_POP3_LIST_RX;
48
49 case MU_POP3_LIST_RX:
50 /* The mu_iterator_t will read the stream and set the state to
51 MU_POP3_NO_STATE when done. */
52 break;
53
54 /* They must deal with the error first by reopening. */
55 case MU_POP3_ERROR:
56 status = ECANCELED;
57 break;
58
59 default:
60 status = EINPROGRESS;
61 }
62
63 return status;
64 }
...@@ -21,51 +21,19 @@ ...@@ -21,51 +21,19 @@
21 # include <config.h> 21 # include <config.h>
22 #endif 22 #endif
23 23
24 #include <string.h>
25 #include <errno.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <mailutils/sys/pop3.h> 24 #include <mailutils/sys/pop3.h>
29 25
30 int 26 int
31 mu_pop3_list_all (mu_pop3_t pop3, mu_iterator_t *piterator) 27 mu_pop3_list_all (mu_pop3_t pop3, mu_iterator_t *piterator)
32 { 28 {
33 int status = 0; 29 int status = mu_pop3_list_cmd (pop3);
34 30
35 if (pop3 == NULL) 31 if (status)
36 return EINVAL; 32 return status;
37 if (piterator == NULL)
38 return MU_ERR_OUT_PTR_NULL;
39 33
40 switch (pop3->state) 34 status = mu_pop3_iterator_create (pop3, piterator);
41 { 35 MU_POP3_CHECK_ERROR (pop3, status);
42 case MU_POP3_NO_STATE: 36 pop3->state = MU_POP3_LIST_RX;
43 status = mu_pop3_writeline (pop3, "LIST\r\n");
44 MU_POP3_CHECK_ERROR (pop3, status);
45 MU_POP3_FCLR (pop3, MU_POP3_ACK);
46 pop3->state = MU_POP3_LIST;
47
48 case MU_POP3_LIST:
49 status = mu_pop3_response (pop3, NULL);
50 MU_POP3_CHECK_EAGAIN (pop3, status);
51 MU_POP3_CHECK_OK (pop3);
52 status = mu_pop3_iterator_create (pop3, piterator);
53 MU_POP3_CHECK_ERROR (pop3, status);
54 pop3->state = MU_POP3_LIST_RX;
55
56 case MU_POP3_LIST_RX:
57 /* The mu_iterator_t will read the stream and set the state to
58 MU_POP3_NO_STATE when done. */
59 break;
60
61 /* They must deal with the error first by reopening. */
62 case MU_POP3_ERROR:
63 status = ECANCELED;
64 break;
65
66 default:
67 status = EINPROGRESS;
68 }
69 37
70 return status; 38 return status;
71 } 39 }
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2004, 2007, 2010 Free Software
3 Foundation, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General
16 Public License along with this library; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301 USA */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include <mailutils/sys/pop3.h>
25
26 int
27 mu_pop3_list_all_stream (mu_pop3_t pop3, mu_stream_t *pstream)
28 {
29 int status = mu_pop3_list_cmd (pop3);
30
31 if (status)
32 return status;
33
34 status = mu_pop3_stream_create (pop3, pstream);
35 MU_POP3_CHECK_ERROR (pop3, status);
36 pop3->state = MU_POP3_LIST_RX;
37
38 return status;
39 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2003, 2004, 2005, 2007, 2010 Free Software Foundation,
3 Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General
16 Public License along with this library; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301 USA */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include <string.h>
25 #include <mailutils/stream.h>
26 #include <mailutils/list.h>
27 #include <mailutils/cctype.h>
28 #include <mailutils/cstr.h>
29 #include <mailutils/sys/pop3.h>
30
31 int
32 mu_pop3_stream_to_list (mu_pop3_t pop3, mu_stream_t stream, mu_list_t list)
33 {
34 int status;
35 size_t n;
36
37 while (mu_stream_getline (stream, &pop3->rdbuf, &pop3->rdsize, &n) == 0
38 && n > 0)
39 {
40 char *np = strdup (pop3->rdbuf);
41 if (!np)
42 {
43 status = ENOMEM;
44 break;
45 }
46 mu_rtrim_class (np, MU_CTYPE_SPACE);
47 status = mu_list_append (list, np);
48 if (status)
49 break;
50 }
51 return status;
52 }
53
54 int
55 mu_pop3_read_list (mu_pop3_t pop3, mu_list_t list)
56 {
57 mu_stream_t stream;
58 int status = mu_pop3_stream_create (pop3, &stream);
59 if (status)
60 return status;
61 status = mu_pop3_stream_to_list (pop3, stream, list);
62 mu_stream_destroy (&stream);
63 return status;
64 }
65
...@@ -48,12 +48,11 @@ mu_pop3_retr (mu_pop3_t pop3, unsigned int msgno, mu_stream_t *pstream) ...@@ -48,12 +48,11 @@ mu_pop3_retr (mu_pop3_t pop3, unsigned int msgno, mu_stream_t *pstream)
48 status = mu_pop3_response (pop3, NULL); 48 status = mu_pop3_response (pop3, NULL);
49 MU_POP3_CHECK_EAGAIN (pop3, status); 49 MU_POP3_CHECK_EAGAIN (pop3, status);
50 MU_POP3_CHECK_OK (pop3); 50 MU_POP3_CHECK_OK (pop3);
51 status = mu_pop3_stream_create (pop3, pstream);
52 MU_POP3_CHECK_ERROR (pop3, status);
51 pop3->state = MU_POP3_RETR_RX; 53 pop3->state = MU_POP3_RETR_RX;
52 54
53 case MU_POP3_RETR_RX: 55 case MU_POP3_RETR_RX:
54 status = mu_pop3_stream_create (pop3, pstream);
55 MU_POP3_CHECK_ERROR (pop3, status);
56 pop3->state = MU_POP3_NO_STATE;
57 break; 56 break;
58 57
59 /* They must deal with the error first by reopening. */ 58 /* They must deal with the error first by reopening. */
......
...@@ -39,6 +39,7 @@ struct mu_pop3_stream ...@@ -39,6 +39,7 @@ struct mu_pop3_stream
39 enum pop3_decode_state 39 enum pop3_decode_state
40 { 40 {
41 pds_init, /* initial state */ 41 pds_init, /* initial state */
42 pds_char, /* Any character excepting [\r\n.] */
42 pds_cr, /* prev. char was \r */ 43 pds_cr, /* prev. char was \r */
43 pds_crlf, /* 2 prev. char were \r\n */ 44 pds_crlf, /* 2 prev. char were \r\n */
44 pds_dot, /* 3 prev. chars were \r\n. */ 45 pds_dot, /* 3 prev. chars were \r\n. */
...@@ -56,6 +57,16 @@ newstate (int state, int c) ...@@ -56,6 +57,16 @@ newstate (int state, int c)
56 { 57 {
57 case '\r': 58 case '\r':
58 return pds_cr; 59 return pds_cr;
60 case '.':
61 return pds_dot;
62 }
63 break;
64
65 case pds_char:
66 switch (c)
67 {
68 case '\r':
69 return pds_cr;
59 } 70 }
60 break; 71 break;
61 72
...@@ -93,7 +104,7 @@ newstate (int state, int c) ...@@ -93,7 +104,7 @@ newstate (int state, int c)
93 return pds_end; 104 return pds_end;
94 } 105 }
95 } 106 }
96 return pds_init; 107 return pds_char;
97 } 108 }
98 109
99 /* Move min(isize,osize) bytes from iptr to optr, replacing each \r\n 110 /* Move min(isize,osize) bytes from iptr to optr, replacing each \r\n
...@@ -140,7 +151,7 @@ _pop3_decoder (void *xd, ...@@ -140,7 +151,7 @@ _pop3_decoder (void *xd,
140 if (*iptr == '\n') 151 if (*iptr == '\n')
141 continue; 152 continue;
142 } 153 }
143 else if (c == '.' && *pstate == pds_crlf) 154 else if (c == '.' && (*pstate == pds_init || *pstate == pds_crlf))
144 { 155 {
145 /* Make sure we have two more characters in the buffer */ 156 /* Make sure we have two more characters in the buffer */
146 if (i + 2 == isize) 157 if (i + 2 == isize)
...@@ -164,16 +175,39 @@ _pop3_decoder (void *xd, ...@@ -164,16 +175,39 @@ _pop3_decoder (void *xd,
164 return mu_filter_ok; 175 return mu_filter_ok;
165 } 176 }
166 177
178 static void
179 _pop3_event_cb (mu_stream_t str, int ev, int flags)
180 {
181 if (ev == _MU_STR_EVENT_SET)
182 {
183 mu_transport_t trans[2];
184
185 if (mu_stream_ioctl (str, MU_IOCTL_GET_TRANSPORT, trans) == 0)
186 {
187 struct mu_pop3_stream *sp = (struct mu_pop3_stream *) trans[0];
188 sp->pop3->state = MU_POP3_NO_STATE;
189 }
190 }
191 }
192
167 static int 193 static int
168 mu_pop3_filter_create (mu_stream_t *pstream, mu_stream_t stream) 194 mu_pop3_filter_create (mu_stream_t *pstream, mu_stream_t stream)
169 { 195 {
196 int rc;
170 int *state = malloc (sizeof (*state)); 197 int *state = malloc (sizeof (*state));
171 if (!state) 198 if (!state)
172 return ENOMEM; 199 return ENOMEM;
173 return mu_filter_stream_create (pstream, stream, 200 rc = mu_filter_stream_create (pstream, stream,
174 MU_FILTER_DECODE, 201 MU_FILTER_DECODE,
175 _pop3_decoder, state, 202 _pop3_decoder, state,
176 MU_STREAM_READ); 203 MU_STREAM_READ);
204 if (rc == 0)
205 {
206 mu_stream_t str = *pstream;
207 str->event_cb = _pop3_event_cb;
208 str->event_mask = _MU_STR_EOF;
209 }
210 return rc;
177 } 211 }
178 212
179 213
...@@ -257,6 +291,7 @@ mu_pop3_stream_create (mu_pop3_t pop3, mu_stream_t *pstream) ...@@ -257,6 +291,7 @@ mu_pop3_stream_create (mu_pop3_t pop3, mu_stream_t *pstream)
257 sp->stream.readdelim = _mu_pop3_readdelim; 291 sp->stream.readdelim = _mu_pop3_readdelim;
258 sp->stream.flush = _mu_pop3_flush; 292 sp->stream.flush = _mu_pop3_flush;
259 sp->stream.wait = _mu_pop3_wait; 293 sp->stream.wait = _mu_pop3_wait;
294
260 sp->pop3 = pop3; 295 sp->pop3 = pop3;
261 sp->done = 0; 296 sp->done = 0;
262 str = (mu_stream_t) sp; 297 str = (mu_stream_t) sp;
......
...@@ -48,12 +48,11 @@ mu_pop3_top (mu_pop3_t pop3, unsigned msgno, unsigned int lines, ...@@ -48,12 +48,11 @@ mu_pop3_top (mu_pop3_t pop3, unsigned msgno, unsigned int lines,
48 status = mu_pop3_response (pop3, NULL); 48 status = mu_pop3_response (pop3, NULL);
49 MU_POP3_CHECK_EAGAIN (pop3, status); 49 MU_POP3_CHECK_EAGAIN (pop3, status);
50 MU_POP3_CHECK_OK (pop3); 50 MU_POP3_CHECK_OK (pop3);
51 status = mu_pop3_stream_create (pop3, pstream);
52 MU_POP3_CHECK_ERROR (pop3, status);
51 pop3->state = MU_POP3_TOP_RX; 53 pop3->state = MU_POP3_TOP_RX;
52 54
53 case MU_POP3_TOP_RX: 55 case MU_POP3_TOP_RX:
54 status = mu_pop3_stream_create (pop3, pstream);
55 MU_POP3_CHECK_ERROR (pop3, status);
56 pop3->state = MU_POP3_NO_STATE;
57 break; 56 break;
58 57
59 /* They must deal with the error first by reopening. */ 58 /* They must deal with the error first by reopening. */
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2003, 2004, 2007, 2010 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library 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 GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library; if not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301 USA */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <stdlib.h>
24 #include <mailutils/sys/pop3.h>
25
26 int
27 mu_pop3_uidl_all_cmd (mu_pop3_t pop3)
28 {
29 int status = 0;
30
31 if (pop3 == NULL)
32 return EINVAL;
33
34 switch (pop3->state)
35 {
36 case MU_POP3_NO_STATE:
37 status = mu_pop3_writeline (pop3, "UIDL\r\n");
38 MU_POP3_CHECK_ERROR (pop3, status);
39 MU_POP3_FCLR (pop3, MU_POP3_ACK);
40 pop3->state = MU_POP3_UIDL;
41
42 case MU_POP3_UIDL:
43 status = mu_pop3_response (pop3, NULL);
44 MU_POP3_CHECK_EAGAIN (pop3, status);
45 MU_POP3_CHECK_OK (pop3);
46 pop3->state = MU_POP3_UIDL_RX;
47
48 case MU_POP3_UIDL_RX:
49 break;
50
51 /* They must deal with the error first by reopening. */
52 case MU_POP3_ERROR:
53 status = ECANCELED;
54 break;
55
56 default:
57 status = EINPROGRESS;
58 }
59
60 return status;
61 }
...@@ -20,50 +20,17 @@ ...@@ -20,50 +20,17 @@
20 # include <config.h> 20 # include <config.h>
21 #endif 21 #endif
22 22
23 #include <string.h>
24 # include <errno.h>
25 #include <stdlib.h>
26 #include <mailutils/sys/pop3.h> 23 #include <mailutils/sys/pop3.h>
27 24
28 int 25 int
29 mu_pop3_uidl_all (mu_pop3_t pop3, mu_iterator_t *piterator) 26 mu_pop3_uidl_all (mu_pop3_t pop3, mu_iterator_t *piterator)
30 { 27 {
31 int status = 0; 28 int status = mu_pop3_uidl_all_cmd (pop3);
32 29 if (status)
33 if (pop3 == NULL) 30 return status;
34 return EINVAL; 31 status = mu_pop3_iterator_create (pop3, piterator);
35 if (piterator == NULL) 32 MU_POP3_CHECK_ERROR (pop3, status);
36 return MU_ERR_OUT_PTR_NULL; 33 pop3->state = MU_POP3_UIDL_RX;
37
38 switch (pop3->state)
39 {
40 case MU_POP3_NO_STATE:
41 status = mu_pop3_writeline (pop3, "UIDL\r\n");
42 MU_POP3_CHECK_ERROR (pop3, status);
43 MU_POP3_FCLR (pop3, MU_POP3_ACK);
44 pop3->state = MU_POP3_UIDL;
45
46 case MU_POP3_UIDL:
47 status = mu_pop3_response (pop3, NULL);
48 MU_POP3_CHECK_EAGAIN (pop3, status);
49 MU_POP3_CHECK_OK (pop3);
50 status = mu_pop3_iterator_create (pop3, piterator);
51 MU_POP3_CHECK_ERROR (pop3, status);
52 pop3->state = MU_POP3_UIDL_RX;
53
54 case MU_POP3_UIDL_RX:
55 /* The mu_iterator_t will read the stream and set the state to
56 MU_POP3_NO_STATE when done. */
57 break;
58
59 /* They must deal with the error first by reopening. */
60 case MU_POP3_ERROR:
61 status = ECANCELED;
62 break;
63
64 default:
65 status = EINPROGRESS;
66 }
67 34
68 return status; 35 return status;
69 } 36 }
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2003, 2004, 2007, 2010 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library 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 GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library; if not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301 USA */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <mailutils/sys/pop3.h>
24
25 int
26 mu_pop3_uidl_all_stream (mu_pop3_t pop3, mu_stream_t *pstream)
27 {
28 int status = mu_pop3_uidl_all_cmd (pop3);
29 if (status)
30 return status;
31 status = mu_pop3_stream_create (pop3, pstream);
32 MU_POP3_CHECK_ERROR (pop3, status);
33 pop3->state = MU_POP3_UIDL_RX;
34
35 return status;
36 }
...@@ -164,7 +164,7 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret) ...@@ -164,7 +164,7 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret)
164 return MU_ERR_FAILURE; /* FIXME: special error code? */ 164 return MU_ERR_FAILURE; /* FIXME: special error code? */
165 if (iobuf.eof) 165 if (iobuf.eof)
166 { 166 {
167 stream->flags |= _MU_STR_EOF; 167 _mu_stream_seteof (stream);
168 stop = 1; 168 stop = 1;
169 } 169 }
170 break; 170 break;
......
...@@ -32,6 +32,22 @@ ...@@ -32,6 +32,22 @@
32 #include <mailutils/stream.h> 32 #include <mailutils/stream.h>
33 #include <mailutils/sys/stream.h> 33 #include <mailutils/sys/stream.h>
34 34
35 static void
36 _stream_setflag (struct _mu_stream *stream, int flag)
37 {
38 if (stream->event_cb && (stream->event_mask & flag))
39 stream->event_cb (stream, _MU_STR_EVENT_SET, flag);
40 stream->flags |= flag;
41 }
42
43 static void
44 _stream_clrflag (struct _mu_stream *stream, int flag)
45 {
46 if (stream->event_cb && (stream->event_mask & flag))
47 stream->event_cb (stream, _MU_STR_EVENT_CLR, flag);
48 stream->flags &= ~flag;
49 }
50
35 int 51 int
36 mu_stream_seterr (struct _mu_stream *stream, int code, int perm) 52 mu_stream_seterr (struct _mu_stream *stream, int code, int perm)
37 { 53 {
...@@ -45,12 +61,23 @@ mu_stream_seterr (struct _mu_stream *stream, int code, int perm) ...@@ -45,12 +61,23 @@ mu_stream_seterr (struct _mu_stream *stream, int code, int perm)
45 61
46 default: 62 default:
47 if (perm) 63 if (perm)
48 stream->flags |= _MU_STR_ERR; 64 _stream_setflag (stream, _MU_STR_ERR);
49 } 65 }
50 return code; 66 return code;
51 } 67 }
52 68
53 #define _stream_cleareof(s) ((s)->flags &= ~_MU_STR_EOF) 69 void
70 _mu_stream_cleareof (mu_stream_t str)
71 {
72 _stream_clrflag (str, _MU_STR_EOF);
73 }
74
75 void
76 _mu_stream_seteof (mu_stream_t str)
77 {
78 _stream_setflag (str, _MU_STR_EOF);
79 }
80
54 #define _stream_advance_buffer(s,n) ((s)->cur += n, (s)->level -= n) 81 #define _stream_advance_buffer(s,n) ((s)->cur += n, (s)->level -= n)
55 #define _stream_buffer_offset(s) ((s)->cur - (s)->buffer) 82 #define _stream_buffer_offset(s) ((s)->cur - (s)->buffer)
56 #define _stream_orig_level(s) ((s)->level + _stream_buffer_offset (s)) 83 #define _stream_orig_level(s) ((s)->level + _stream_buffer_offset (s))
...@@ -82,9 +109,13 @@ _stream_fill_buffer (struct _mu_stream *stream) ...@@ -82,9 +109,13 @@ _stream_fill_buffer (struct _mu_stream *stream)
82 for (n = 0; 109 for (n = 0;
83 n < stream->bufsize 110 n < stream->bufsize
84 && (rc = mu_stream_read_unbuffered (stream, 111 && (rc = mu_stream_read_unbuffered (stream,
85 &c, 1, 0, &rdn)) == 0 112 &c, 1, 0, &rdn)) == 0;)
86 && rdn; )
87 { 113 {
114 if (rdn == 0)
115 {
116 _stream_setflag (stream, _MU_STR_EOF);
117 break;
118 }
88 stream->buffer[n++] = c; 119 stream->buffer[n++] = c;
89 if (c == '\n') 120 if (c == '\n')
90 break; 121 break;
...@@ -175,7 +206,7 @@ _stream_flush_buffer (struct _mu_stream *stream, int all) ...@@ -175,7 +206,7 @@ _stream_flush_buffer (struct _mu_stream *stream, int all)
175 } 206 }
176 else 207 else
177 { 208 {
178 stream->flags &= ~_MU_STR_DIRTY; 209 _stream_clrflag (stream, _MU_STR_DIRTY);
179 stream->level = 0; 210 stream->level = 0;
180 } 211 }
181 stream->cur = stream->buffer; 212 stream->cur = stream->buffer;
...@@ -269,7 +300,7 @@ void ...@@ -269,7 +300,7 @@ void
269 mu_stream_clearerr (mu_stream_t stream) 300 mu_stream_clearerr (mu_stream_t stream)
270 { 301 {
271 stream->last_err = 0; 302 stream->last_err = 0;
272 stream->flags &= ~_MU_STR_ERR; 303 _stream_clrflag (stream, _MU_STR_ERR);
273 } 304 }
274 305
275 int 306 int
...@@ -327,7 +358,7 @@ mu_stream_seek (mu_stream_t stream, mu_off_t offset, int whence, ...@@ -327,7 +358,7 @@ mu_stream_seek (mu_stream_t stream, mu_off_t offset, int whence,
327 return rc; 358 return rc;
328 if (rc) 359 if (rc)
329 return mu_stream_seterr (stream, rc, 1); 360 return mu_stream_seterr (stream, rc, 1);
330 _stream_cleareof (stream); 361 _mu_stream_cleareof (stream);
331 } 362 }
332 363
333 if (pres) 364 if (pres)
...@@ -469,7 +500,7 @@ mu_stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size, ...@@ -469,7 +500,7 @@ mu_stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size,
469 { 500 {
470 if (rdbytes == 0) 501 if (rdbytes == 0)
471 { 502 {
472 stream->flags |= _MU_STR_EOF; 503 _stream_setflag (stream, _MU_STR_EOF);
473 break; 504 break;
474 } 505 }
475 buf += rdbytes; 506 buf += rdbytes;
...@@ -487,7 +518,7 @@ mu_stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size, ...@@ -487,7 +518,7 @@ mu_stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size,
487 if (rc == 0) 518 if (rc == 0)
488 { 519 {
489 if (nread == 0) 520 if (nread == 0)
490 stream->flags |= _MU_STR_EOF; 521 _stream_setflag (stream, _MU_STR_EOF);
491 stream->bytes_in += nread; 522 stream->bytes_in += nread;
492 } 523 }
493 mu_stream_seterr (stream, rc, rc != 0); 524 mu_stream_seterr (stream, rc, rc != 0);
...@@ -551,7 +582,7 @@ mu_stream_write_unbuffered (mu_stream_t stream, ...@@ -551,7 +582,7 @@ mu_stream_write_unbuffered (mu_stream_t stream,
551 if (rc == 0) 582 if (rc == 0)
552 stream->bytes_out += nwritten; 583 stream->bytes_out += nwritten;
553 } 584 }
554 stream->flags |= _MU_STR_WRT; 585 _stream_setflag (stream, _MU_STR_WRT);
555 stream->offset += nwritten; 586 stream->offset += nwritten;
556 if (pnwritten) 587 if (pnwritten)
557 *pnwritten = nwritten; 588 *pnwritten = nwritten;
...@@ -806,7 +837,7 @@ mu_stream_write (mu_stream_t stream, const void *buf, size_t size, ...@@ -806,7 +837,7 @@ mu_stream_write (mu_stream_t stream, const void *buf, size_t size,
806 nbytes += n; 837 nbytes += n;
807 bufp += n; 838 bufp += n;
808 size -= n; 839 size -= n;
809 stream->flags |= _MU_STR_DIRTY; 840 _stream_setflag (stream, _MU_STR_DIRTY);
810 } 841 }
811 if (pnwritten) 842 if (pnwritten)
812 *pnwritten = nbytes; 843 *pnwritten = nbytes;
...@@ -835,7 +866,7 @@ mu_stream_flush (mu_stream_t stream) ...@@ -835,7 +866,7 @@ mu_stream_flush (mu_stream_t stream)
835 return rc; 866 return rc;
836 if ((stream->flags & _MU_STR_WRT) && stream->flush) 867 if ((stream->flags & _MU_STR_WRT) && stream->flush)
837 return stream->flush (stream); 868 return stream->flush (stream);
838 stream->flags &= ~_MU_STR_WRT; 869 _stream_clrflag (stream, _MU_STR_WRT);
839 return 0; 870 return 0;
840 } 871 }
841 872
......