Commit 4ec2ac41 4ec2ac41eaa6dc77165820d3335aeb859da644d6 by Alain Magloire

* mailbox2/pop3/*: Pop3 functions are thread-safe and cancel-safe.

	The problem is monitor.h, we will probably end up doing a monitor.h.in
	and set at compile time if threading is enable or not.
1 parent 1fadf5f9
1 2001-07-01 Alain Magloire 1 2001-07-01 Alain Magloire
2 2
3 * mailbox2/pop3/*: Pop3 functions are thread-safe and cancel-safe.
4 The problem is monitor.h, we will probably end up doing a monitor.h.in
5 and set a compile time if threading was enable or not.
6
7 2001-07-01 Alain Magloire
8
3 * mail/util.c (util_expand_msglist): Cleanup the expand by pattern 9 * mail/util.c (util_expand_msglist): Cleanup the expand by pattern
4 by moving some code in util_strupper(), the comparison must be 10 by moving some code in util_strupper(), the comparison must be
5 case insensitive. 11 case insensitive.
......
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 #ifndef _MAILUTILS_MONITOR_H
19 #define _MAILUTILS_MONITOR_H
20
21 #include <unistd.h>
22 #ifdef _POSIX_THREADS
23 # include <pthread.h>
24 #endif
25
26 #ifdef _POSIX_THREADS
27
28 # define monitor_t pthread_mutex_t
29
30 # define MU_MONITOR_INITIALIZER PTHREAD_MUTEX_INITIALIZER
31
32 # define monitor_create(m) pthread_mutex_init (m, NULL)
33 # define monitor_destroy(m) pthread_mutex_destroy (&m)
34
35 # define monitor_cleanup_push(routine, arg) pthread_cleanup_push (routine, arg)
36 # define monitor_cleanup_pop(execute) pthread_cleanup_pop (execute)
37
38 # define monitor_lock(m) pthread_mutex_lock (&m)
39 # define monitor_unlock(m) pthread_mutex_unlock (&m)
40
41 #else
42
43 # define monitor_t int
44
45 # define MU_MONITOR_INITIALIZER 0
46
47 # define monitor_create(m) (*m = 0)
48 # define monitor_destroy(m) (m = 0)
49
50 # define monitor_cleanup_push(routine, arg) {
51 # define monitor_cleanup_pop(execute) }
52
53 # define monitor_rdlock(m) (m = 1)
54 # define monitor_unlock(m) (m = 0)
55
56 #endif
57
58 #endif /* _MAILUTILS_MONITOR_H */
...@@ -22,20 +22,17 @@ ...@@ -22,20 +22,17 @@
22 #include <stdio.h> 22 #include <stdio.h>
23 #include <string.h> 23 #include <string.h>
24 24
25 #include <mailutils/sys/pop3.h>
26 #include <mailutils/md5-rsa.h> 25 #include <mailutils/md5-rsa.h>
26 #include <mailutils/sys/pop3.h>
27 27
28 /* 28 /*
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 int 32 static int
33 pop3_apop (pop3_t pop3, const char *user, const char *secret) 33 pop3_apop0 (pop3_t pop3, const char *user, const char *secret)
34 { 34 {
35 int status = 0; 35 int status;
36
37 if (pop3 == NULL)
38 return MU_ERROR_INVALID_PARAMETER;
39 36
40 /* The server did not offer a time stamp in the greeting, bailout early. */ 37 /* The server did not offer a time stamp in the greeting, bailout early. */
41 if (pop3->timestamp == NULL) 38 if (pop3->timestamp == NULL)
...@@ -93,3 +90,19 @@ pop3_apop (pop3_t pop3, const char *user, const char *secret) ...@@ -93,3 +90,19 @@ pop3_apop (pop3_t pop3, const char *user, const char *secret)
93 90
94 return status; 91 return status;
95 } 92 }
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,13 +24,10 @@ ...@@ -24,13 +24,10 @@
24 #include <stddef.h> 24 #include <stddef.h>
25 #include <mailutils/sys/pop3.h> 25 #include <mailutils/sys/pop3.h>
26 26
27 int 27 static int
28 pop3_capa (pop3_t pop3, iterator_t *piterator) 28 pop3_capa0 (pop3_t pop3, iterator_t *piterator)
29 { 29 {
30 int status = 0; 30 int status;
31
32 if (pop3 == NULL || piterator == NULL)
33 return MU_ERROR_INVALID_PARAMETER;
34 31
35 switch (pop3->state) 32 switch (pop3->state)
36 { 33 {
...@@ -67,3 +64,19 @@ pop3_capa (pop3_t pop3, iterator_t *piterator) ...@@ -67,3 +64,19 @@ pop3_capa (pop3_t pop3, iterator_t *piterator)
67 64
68 return status; 65 return status;
69 } 66 }
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 }
......
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 <stdio.h>
23 #include <string.h>
24
25 #include <mailutils/sys/pop3.h>
26 #include <mailutils/md5-rsa.h>
27 #include <mailutils/monitor.h>
28
29 void
30 pop3_cleanup (void *arg)
31 {
32 pop3_t pop3 = (pop3_t)arg;
33 monitor_unlock (pop3->lock);
34 pop3->state = POP3_ERROR;
35 }
...@@ -22,22 +22,21 @@ ...@@ -22,22 +22,21 @@
22 #include <sys/time.h> 22 #include <sys/time.h>
23 #include <unistd.h> 23 #include <unistd.h>
24 #include <stdlib.h> 24 #include <stdlib.h>
25 #ifdef HAVE_STRING_H
25 #include <string.h> 26 #include <string.h>
27 #else
26 #include <strings.h> 28 #include <strings.h>
29 #endif
27 #include <mailutils/sys/pop3.h> 30 #include <mailutils/sys/pop3.h>
28 31
29 static int pop3_sleep (int seconds); 32 static int pop3_sleep (int seconds);
30 33
31 /* 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
32 that may contain a timestamp for APOP. */ 35 that may contain a timestamp for APOP. */
33 int 36 static int
34 pop3_connect (pop3_t pop3, const char *host, unsigned int port) 37 pop3_connect0 (pop3_t pop3, const char *host, unsigned int port)
35 { 38 {
36 int status = 0; 39 int status;
37
38 /* Sanity checks. */
39 if (pop3 == NULL || host == NULL)
40 return MU_ERROR_INVALID_PARAMETER;
41 40
42 /* Default is 110. */ 41 /* Default is 110. */
43 if (!port) 42 if (!port)
...@@ -131,3 +130,21 @@ pop3_sleep (int seconds) ...@@ -131,3 +130,21 @@ pop3_sleep (int seconds)
131 tval.tv_usec = 0; 130 tval.tv_usec = 0;
132 return select (1, NULL, NULL, NULL, &tval); 131 return select (1, NULL, NULL, NULL, &tval);
133 } 132 }
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 }
......
...@@ -60,6 +60,8 @@ pop3_create (pop3_t *ppop3) ...@@ -60,6 +60,8 @@ pop3_create (pop3_t *ppop3)
60 pop3->timeout = 10 * 60; /* The default Timeout is 10 minutes. */ 60 pop3->timeout = 10 * 60; /* The default Timeout is 10 minutes. */
61 pop3->acknowledge = 0; /* No Ack received. */ 61 pop3->acknowledge = 0; /* No Ack received. */
62 62
63 monitor_create (&(pop3->lock));
64
63 *ppop3 = pop3; 65 *ppop3 = pop3;
64 return 0; /* Okdoke. */ 66 return 0; /* Okdoke. */
65 } 67 }
......
...@@ -26,13 +26,10 @@ ...@@ -26,13 +26,10 @@
26 26
27 #include <mailutils/sys/pop3.h> 27 #include <mailutils/sys/pop3.h>
28 28
29 int 29 static int
30 pop3_dele (pop3_t pop3, unsigned msgno) 30 pop3_dele0 (pop3_t pop3, unsigned msgno)
31 { 31 {
32 int status = 0; 32 int status;
33
34 if (pop3 == NULL || msgno == 0)
35 return MU_ERROR_INVALID_PARAMETER;
36 33
37 switch (pop3->state) 34 switch (pop3->state)
38 { 35 {
...@@ -64,3 +61,19 @@ pop3_dele (pop3_t pop3, unsigned msgno) ...@@ -64,3 +61,19 @@ pop3_dele (pop3_t pop3, unsigned msgno)
64 } 61 }
65 return status; 62 return status;
66 } 63 }
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 }
......
...@@ -37,6 +37,8 @@ pop3_destroy (pop3_t pop3) ...@@ -37,6 +37,8 @@ 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
40 free (pop3); 42 free (pop3);
41 } 43 }
42 } 44 }
......
...@@ -24,13 +24,9 @@ ...@@ -24,13 +24,9 @@
24 #include <string.h> 24 #include <string.h>
25 25
26 /* Sudden death. */ 26 /* Sudden death. */
27 int 27 static int
28 pop3_disconnect (pop3_t pop3) 28 pop3_disconnect0 (pop3_t pop3)
29 { 29 {
30 /* Sanity checks. */
31 if (pop3 == NULL)
32 return MU_ERROR_INVALID_PARAMETER;
33
34 /* We can keep some of the fields, if they decide to pop3_open() again but 30 /* We can keep some of the fields, if they decide to pop3_open() again but
35 clear the states. */ 31 clear the states. */
36 pop3->state = POP3_NO_STATE; 32 pop3->state = POP3_NO_STATE;
...@@ -48,3 +44,20 @@ pop3_disconnect (pop3_t pop3) ...@@ -48,3 +44,20 @@ pop3_disconnect (pop3_t pop3)
48 return stream_close (pop3->stream); 44 return stream_close (pop3->stream);
49 return 0; 45 return 0;
50 } 46 }
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 }
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
25 #include <stdlib.h> 25 #include <stdlib.h>
26 #include <stdio.h> 26 #include <stdio.h>
27 #include <mailutils/sys/pop3.h> 27 #include <mailutils/sys/pop3.h>
28 #include <mailutils/sys/iterator.h>
29 28
30 static int p_add_ref __P ((iterator_t)); 29 static int p_add_ref __P ((iterator_t));
31 static int p_release __P ((iterator_t)); 30 static int p_release __P ((iterator_t));
...@@ -62,6 +61,7 @@ pop3_iterator_create (pop3_t pop3, iterator_t *piterator) ...@@ -62,6 +61,7 @@ pop3_iterator_create (pop3_t pop3, iterator_t *piterator)
62 p_iterator->item = NULL; 61 p_iterator->item = NULL;
63 p_iterator->done = 0; 62 p_iterator->done = 0;
64 p_iterator->pop3= pop3; 63 p_iterator->pop3= pop3;
64 monitor_create (&p_iterator->lock);
65 *piterator = &p_iterator->base; 65 *piterator = &p_iterator->base;
66 return 0; 66 return 0;
67 } 67 }
...@@ -69,38 +69,57 @@ pop3_iterator_create (pop3_t pop3, iterator_t *piterator) ...@@ -69,38 +69,57 @@ pop3_iterator_create (pop3_t pop3, iterator_t *piterator)
69 static int 69 static int
70 p_add_ref (iterator_t iterator) 70 p_add_ref (iterator_t iterator)
71 { 71 {
72 int status = 0;
72 struct p_iterator *p_iterator = (struct p_iterator *)iterator; 73 struct p_iterator *p_iterator = (struct p_iterator *)iterator;
73 return ++p_iterator->ref; 74 if (p_iterator)
75 {
76 monitor_lock (p_iterator->lock);
77 status = ++p_iterator->ref;
78 monitor_unlock (p_iterator->lock);
79 }
80 return status;
74 } 81 }
75 82
76 static int 83 static int
77 p_release (iterator_t iterator) 84 p_release (iterator_t iterator)
78 { 85 {
86 int status = 0;
79 struct p_iterator *p_iterator = (struct p_iterator *)iterator; 87 struct p_iterator *p_iterator = (struct p_iterator *)iterator;
80 if (--p_iterator->ref == 0) 88 if (p_iterator)
81 { 89 {
82 p_destroy (iterator); 90 monitor_lock (p_iterator->lock);
83 return 0; 91 status = --p_iterator->ref;
92 if (status <= 0)
93 {
94 monitor_unlock (p_iterator->lock);
95 p_destroy (iterator);
96 return 0;
97 }
98 monitor_unlock (p_iterator->lock);
84 } 99 }
85 return p_iterator->ref; 100 return status;
86 } 101 }
87 102
88 static int 103 static int
89 p_destroy (iterator_t iterator) 104 p_destroy (iterator_t iterator)
90 { 105 {
91 struct p_iterator *p_iterator = (struct p_iterator *)iterator; 106 struct p_iterator *p_iterator = (struct p_iterator *)iterator;
92 if (!p_iterator->done) 107 if (p_iterator)
93 { 108 {
94 char buf[128]; 109 if (!p_iterator->done)
95 size_t n = 0; 110 {
96 while (pop3_readline (p_iterator->pop3, buf, sizeof buf, &n) > 0 111 char buf[128];
97 && n > 0) 112 size_t n = 0;
98 n = 0; 113 while (pop3_readline (p_iterator->pop3, buf, sizeof buf, &n) > 0
114 && n > 0)
115 n = 0;
116 }
117 if (p_iterator->item)
118 free (p_iterator->item);
119 p_iterator->pop3->state = POP3_NO_STATE;
120 monitor_destroy (p_iterator->lock);
121 free (p_iterator);
99 } 122 }
100 if (p_iterator->item)
101 free (p_iterator->item);
102 p_iterator->pop3->state = POP3_NO_STATE;
103 free (iterator);
104 return 0; 123 return 0;
105 } 124 }
106 125
...@@ -116,131 +135,174 @@ p_next (iterator_t iterator) ...@@ -116,131 +135,174 @@ p_next (iterator_t iterator)
116 { 135 {
117 struct p_iterator *p_iterator = (struct p_iterator *)iterator; 136 struct p_iterator *p_iterator = (struct p_iterator *)iterator;
118 size_t n = 0; 137 size_t n = 0;
119 int status; 138 int status = 0;
120
121 if (p_iterator->done)
122 return 0;
123
124 status = pop3_readline (p_iterator->pop3, NULL, 0, &n);
125 if (status != 0)
126 return status;
127 139
128 if (n == 0) 140 if (p_iterator)
129 { 141 {
130 p_iterator->done = 1; 142 monitor_lock (p_iterator->lock);
131 p_iterator->pop3->state = POP3_NO_STATE; 143 if (!p_iterator->done)
132 return 0; 144 {
133 } 145 /* The first readline will not consume the buffer, we just need to
134 146 know how much to read. */
135 if (p_iterator->item) 147 status = pop3_readline (p_iterator->pop3, NULL, 0, &n);
136 free (p_iterator->item); 148 if (status == 0)
137 149 {
138 switch (p_iterator->pop3->state) 150 if (n)
139 { 151 {
140 case POP3_CAPA_RX: 152 switch (p_iterator->pop3->state)
141 { 153 {
142 char *buf; 154 case POP3_CAPA_RX:
143 155 {
144 buf = calloc (n + 1, 1); 156 char *buf;
145 if (buf == NULL) 157 buf = calloc (n + 1, 1);
146 return MU_ERROR_NO_MEMORY; 158 if (buf)
147 159 {
148 /* Consume. */ 160 /* Consume. */
149 pop3_readline (p_iterator->pop3, buf, n + 1, NULL); 161 pop3_readline (p_iterator->pop3, buf, n + 1, NULL);
150 if (n && buf[n - 1] == '\n') 162 if (buf[n - 1] == '\n')
151 buf[n - 1] = '\0'; 163 buf[n - 1] = '\0';
152 p_iterator->item = buf; 164 if (p_iterator->item)
153 } 165 free (p_iterator->item);
154 break; 166 p_iterator->item = buf;
155 167 }
156 case POP3_UIDL_RX: 168 else
157 { 169 status = MU_ERROR_NO_MEMORY;
158 unsigned msgno; 170 break;
159 char *space; 171 }
160 char *buf = calloc (n + 1, 1); 172
161 173 case POP3_UIDL_RX:
162 if (buf == NULL) 174 {
163 return MU_ERROR_NO_MEMORY; 175 struct pop3_uidl_item *pitem;
164 176 char *buf = calloc (n + 1, 1);
165 p_iterator->item = calloc (1, sizeof (struct pop3_uidl_item)); 177 if (buf)
166 if (p_iterator->item == NULL) 178 {
167 return MU_ERROR_NO_MEMORY; 179 if (p_iterator->item)
168 180 {
169 /* Consume. */ 181 pitem = p_iterator->item;
170 pop3_readline (p_iterator->pop3, buf, n + 1, NULL); 182 if (pitem->uidl)
171 msgno = 0; 183 free (pitem->uidl);
172 space = strchr (buf, ' '); 184 free (pitem);
173 if (space) 185 }
174 { 186 p_iterator->item = calloc (1, sizeof *pitem);
175 *space++ = '\0'; 187 pitem = p_iterator->item;
176 msgno = strtoul (buf, NULL, 10); 188 if (pitem)
177 } 189 {
178 if (space && space[strlen (space) - 1] == '\n') 190 unsigned msgno;
179 space[strlen (space) - 1] = '\0'; 191 char *space;
180 if (space == NULL) 192 /* Consume. */
181 space = (char *)""; 193 pop3_readline (p_iterator->pop3, buf,
182 ((struct pop3_uidl_item *)(p_iterator->item))->msgno = msgno; 194 n + 1, NULL);
183 ((struct pop3_uidl_item *)(p_iterator->item))->uidl = strdup (space); 195 msgno = 0;
184 free (buf); 196 /* The format is:
185 } 197 msgno uidlsttring */
186 break; 198 space = strchr (buf, ' ');
187 199 if (space)
188 case POP3_LIST_RX: 200 {
189 { 201 *space++ = '\0';
190 char *buf = calloc (n + 1, 1); 202 msgno = strtoul (buf, NULL, 10);
191 unsigned msgno; 203 }
192 size_t size; 204 if (space && space[strlen (space) - 1] == '\n')
193 205 space[strlen (space) - 1] = '\0';
194 if (buf == NULL) 206 if (space == NULL)
195 return MU_ERROR_NO_MEMORY; 207 space = (char *)"";
196 208 pitem->msgno = msgno;
197 p_iterator->item = calloc (1, sizeof (struct pop3_list_item)); 209 pitem->uidl = strdup (space);
198 if (p_iterator->item == NULL) 210 }
199 return MU_ERROR_NO_MEMORY; 211 else
200 212 status = MU_ERROR_NO_MEMORY;
201 /* Consume. */ 213 free (buf);
202 pop3_readline (p_iterator->pop3, buf, n + 1, NULL); 214 }
203 size = msgno = 0; 215 else
204 sscanf (buf, "%d %d", &msgno, &size); 216 status = MU_ERROR_NO_MEMORY;
205 ((struct pop3_list_item *)(p_iterator->item))->msgno = msgno; 217 break;
206 ((struct pop3_list_item *)(p_iterator->item))->size = size; 218 }
207 free (buf); 219
208 } 220 case POP3_LIST_RX:
209 break; 221 {
210 222 struct pop3_list_item *pitem;
211 default: 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 }
254 }
255 else
256 {
257 p_iterator->done = 1;
258 p_iterator->pop3->state = POP3_NO_STATE;
259 }
260 }
261 }
262 monitor_unlock (p_iterator->lock);
212 } 263 }
213 264 return status;
214 return 0;
215 } 265 }
216 266
217 static int 267 static int
218 p_is_done (iterator_t iterator) 268 p_is_done (iterator_t iterator)
219 { 269 {
220 struct p_iterator *p_iterator = (struct p_iterator *)iterator; 270 struct p_iterator *p_iterator = (struct p_iterator *)iterator;
221 return p_iterator->done; 271 int status = 1;
272 if (p_iterator)
273 {
274 monitor_lock (p_iterator->lock);
275 status = p_iterator->done;
276 monitor_unlock (p_iterator->lock);
277 }
278 return status;
222 } 279 }
223 280
224 static int 281 static int
225 p_current (iterator_t iterator, void *item) 282 p_current (iterator_t iterator, void *item)
226 { 283 {
227 struct p_iterator *p_iterator = (struct p_iterator *)iterator; 284 struct p_iterator *p_iterator = (struct p_iterator *)iterator;
228 if (item) 285 if (p_iterator)
229 { 286 {
230 switch (p_iterator->pop3->state) 287 monitor_lock (p_iterator->lock);
288 if (item)
231 { 289 {
232 case POP3_CAPA_RX: 290 switch (p_iterator->pop3->state)
233 case POP3_UIDL_RX: 291 {
234 *((char **)item) = p_iterator->item; 292 case POP3_CAPA_RX:
235 break; 293 case POP3_UIDL_RX:
236 294 *((char **)item) = p_iterator->item;
237 case POP3_LIST_RX: 295 break;
238 *((struct pop3_list_item **)item) = p_iterator->item; 296
239 break; 297 case POP3_LIST_RX:
240 298 *((struct pop3_list_item **)item) = p_iterator->item;
241 default: 299 break;
300
301 default:
302 }
242 } 303 }
304 p_iterator->item = NULL;
305 monitor_unlock (p_iterator->lock);
243 } 306 }
244 p_iterator->item = NULL;
245 return 0; 307 return 0;
246 } 308 }
......
...@@ -19,22 +19,19 @@ ...@@ -19,22 +19,19 @@
19 # include <config.h> 19 # include <config.h>
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #ifdef HAVE_STRING_H
23 #ifdef HAVE_STRINGS_H 23 # include <string.h>
24 #else
24 # include <strings.h> 25 # include <strings.h>
25 #endif 26 #endif
26 27
27 #include <stdio.h> 28 #include <stdio.h>
28
29 #include <mailutils/sys/pop3.h> 29 #include <mailutils/sys/pop3.h>
30 30
31 int 31 static int
32 pop3_list (pop3_t pop3, unsigned msgno, size_t *psize) 32 pop3_list0 (pop3_t pop3, unsigned msgno, size_t *psize)
33 { 33 {
34 int status = 0; 34 int status;
35
36 if (pop3 == NULL)
37 return MU_ERROR_INVALID_PARAMETER;
38 35
39 switch (pop3->state) 36 switch (pop3->state)
40 { 37 {
...@@ -73,3 +70,18 @@ pop3_list (pop3_t pop3, unsigned msgno, size_t *psize) ...@@ -73,3 +70,18 @@ pop3_list (pop3_t pop3, unsigned msgno, size_t *psize)
73 70
74 return status; 71 return status;
75 } 72 }
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 }
......
...@@ -19,21 +19,19 @@ ...@@ -19,21 +19,19 @@
19 # include <config.h> 19 # include <config.h>
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #ifdef HAVE_STRING_H
23 #ifdef HAVE_STRINGS_H 23 # include <string.h>
24 #else
24 # include <strings.h> 25 # include <strings.h>
25 #endif 26 #endif
26 27
27 #include <stdlib.h> 28 #include <stdlib.h>
28 #include <mailutils/sys/pop3.h> 29 #include <mailutils/sys/pop3.h>
29 30
30 int 31 static int
31 pop3_list_all (pop3_t pop3, iterator_t *piterator) 32 pop3_list_all0 (pop3_t pop3, iterator_t *piterator)
32 { 33 {
33 int status = 0; 34 int status;
34
35 if (pop3 == NULL)
36 return MU_ERROR_INVALID_PARAMETER;
37 35
38 switch (pop3->state) 36 switch (pop3->state)
39 { 37 {
...@@ -72,3 +70,19 @@ pop3_list_all (pop3_t pop3, iterator_t *piterator) ...@@ -72,3 +70,19 @@ pop3_list_all (pop3_t pop3, iterator_t *piterator)
72 70
73 return status; 71 return status;
74 } 72 }
73
74 int
75 pop3_list_all (pop3_t pop3, iterator_t *piterator)
76 {
77 int status;
78
79 if (pop3 == NULL)
80 return MU_ERROR_INVALID_PARAMETER;
81
82 monitor_lock (pop3->lock);
83 monitor_cleanup_push (pop3_cleanup, pop3);
84 status = pop3_list_all0 (pop3, piterator);
85 monitor_unlock (pop3->lock);
86 monitor_cleanup_pop (0);
87 return status;
88 }
......
...@@ -19,20 +19,18 @@ ...@@ -19,20 +19,18 @@
19 # include <config.h> 19 # include <config.h>
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #ifdef HAVE_STRING_H
23 #ifdef HAVE_STRINGS_H 23 # include <string.h>
24 #else
24 # include <strings.h> 25 # include <strings.h>
25 #endif 26 #endif
26 27
27 #include <mailutils/sys/pop3.h> 28 #include <mailutils/sys/pop3.h>
28 29
29 int 30 static int
30 pop3_noop (pop3_t pop3) 31 pop3_noop0 (pop3_t pop3)
31 { 32 {
32 int status = 0; 33 int status;
33
34 if (pop3 == NULL)
35 return MU_ERROR_INVALID_PARAMETER;
36 34
37 switch (pop3->state) 35 switch (pop3->state)
38 { 36 {
...@@ -65,3 +63,20 @@ pop3_noop (pop3_t pop3) ...@@ -65,3 +63,20 @@ pop3_noop (pop3_t pop3)
65 63
66 return status; 64 return status;
67 } 65 }
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 }
......
...@@ -19,20 +19,18 @@ ...@@ -19,20 +19,18 @@
19 # include <config.h> 19 # include <config.h>
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #ifdef HAVE_STRING_H
23 #ifdef HAVE_STRINGS_H 23 # include <string.h>
24 #else
24 # include <strings.h> 25 # include <strings.h>
25 #endif 26 #endif
26 27
27 #include <mailutils/sys/pop3.h> 28 #include <mailutils/sys/pop3.h>
28 29
29 int 30 static int
30 pop3_pass (pop3_t pop3, const char *passwd) 31 pop3_pass0 (pop3_t pop3, const char *passwd)
31 { 32 {
32 int status = 0; 33 int status;
33
34 if (pop3 == NULL)
35 return MU_ERROR_INVALID_PARAMETER;
36 34
37 switch (pop3->state) 35 switch (pop3->state)
38 { 36 {
...@@ -67,3 +65,19 @@ pop3_pass (pop3_t pop3, const char *passwd) ...@@ -67,3 +65,19 @@ pop3_pass (pop3_t pop3, const char *passwd)
67 65
68 return status; 66 return status;
69 } 67 }
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 }
......
...@@ -19,20 +19,18 @@ ...@@ -19,20 +19,18 @@
19 # include <config.h> 19 # include <config.h>
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #ifdef HAVE_STRING_H
23 #ifdef HAVE_STRINGS_H 23 # include <string.h>
24 #else
24 # include <strings.h> 25 # include <strings.h>
25 #endif 26 #endif
26 27
27 #include <mailutils/sys/pop3.h> 28 #include <mailutils/sys/pop3.h>
28 29
29 int 30 static int
30 pop3_quit (pop3_t pop3) 31 pop3_quit0 (pop3_t pop3)
31 { 32 {
32 int status = 0; 33 int status;
33
34 if (pop3 == NULL)
35 return MU_ERROR_INVALID_PARAMETER;
36 34
37 switch (pop3->state) 35 switch (pop3->state)
38 { 36 {
...@@ -60,3 +58,19 @@ pop3_quit (pop3_t pop3) ...@@ -60,3 +58,19 @@ pop3_quit (pop3_t pop3)
60 58
61 return status; 59 return status;
62 } 60 }
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 }
......
...@@ -38,13 +38,20 @@ pop3_response (pop3_t pop3, char *buffer, size_t buflen, size_t *pnread) ...@@ -38,13 +38,20 @@ pop3_response (pop3_t pop3, char *buffer, size_t buflen, size_t *pnread)
38 size_t len = pop3->ack.len - (pop3->ack.ptr - pop3->ack.buf); 38 size_t len = pop3->ack.len - (pop3->ack.ptr - pop3->ack.buf);
39 status = pop3_readline (pop3, pop3->ack.ptr, len, &n); 39 status = pop3_readline (pop3, pop3->ack.ptr, len, &n);
40 pop3->ack.ptr += n; 40 pop3->ack.ptr += n;
41 if (status != 0) 41 if (status == 0)
42 return status; 42 {
43 len = pop3->ack.ptr - pop3->ack.buf; 43 len = pop3->ack.ptr - pop3->ack.buf;
44 if (len && pop3->ack.buf[len - 1] == '\n') 44 if (len && pop3->ack.buf[len - 1] == '\n')
45 pop3->ack.buf[len - 1] = '\0'; 45 pop3->ack.buf[len - 1] = '\0';
46 pop3->acknowledge = 1; /* Flag that we have the ack. */ 46 pop3->acknowledge = 1; /* Flag that we have the ack. */
47 pop3->ack.ptr = pop3->ack.buf; 47 pop3->ack.ptr = pop3->ack.buf;
48 }
49 else
50 {
51 const char *econ = "-ERR POP3 Failed";
52 n = strlen (econ);
53 strcpy (pop3->ack.buf, econ);
54 }
48 } 55 }
49 else 56 else
50 n = strlen (pop3->ack.buf); 57 n = strlen (pop3->ack.buf);
......
...@@ -27,13 +27,10 @@ ...@@ -27,13 +27,10 @@
27 27
28 #include <mailutils/sys/pop3.h> 28 #include <mailutils/sys/pop3.h>
29 29
30 int 30 static int
31 pop3_retr (pop3_t pop3, unsigned msgno, stream_t *pstream) 31 pop3_retr0 (pop3_t pop3, unsigned msgno, stream_t *pstream)
32 { 32 {
33 int status = 0; 33 int status;
34
35 if (pop3 == NULL || pstream == NULL)
36 return MU_ERROR_INVALID_PARAMETER;
37 34
38 switch (pop3->state) 35 switch (pop3->state)
39 { 36 {
...@@ -70,3 +67,19 @@ pop3_retr (pop3_t pop3, unsigned msgno, stream_t *pstream) ...@@ -70,3 +67,19 @@ pop3_retr (pop3_t pop3, unsigned msgno, stream_t *pstream)
70 67
71 return status; 68 return status;
72 } 69 }
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 }
......
...@@ -19,20 +19,18 @@ ...@@ -19,20 +19,18 @@
19 # include <config.h> 19 # include <config.h>
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #ifdef HAVE_STRING_H
23 #ifdef HAVE_STRINGS_H 23 # include <string.h>
24 #else
24 # include <strings.h> 25 # include <strings.h>
25 #endif 26 #endif
26 27
27 #include <mailutils/sys/pop3.h> 28 #include <mailutils/sys/pop3.h>
28 29
29 int 30 static int
30 pop3_rset (pop3_t pop3) 31 pop3_rset0 (pop3_t pop3)
31 { 32 {
32 int status = 0; 33 int status;
33
34 if (pop3 == NULL)
35 return MU_ERROR_INVALID_PARAMETER;
36 34
37 switch (pop3->state) 35 switch (pop3->state)
38 { 36 {
...@@ -65,3 +63,19 @@ pop3_rset (pop3_t pop3) ...@@ -65,3 +63,19 @@ pop3_rset (pop3_t pop3)
65 63
66 return status; 64 return status;
67 } 65 }
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 }
......
...@@ -20,20 +20,18 @@ ...@@ -20,20 +20,18 @@
20 #endif 20 #endif
21 21
22 #include <stdio.h> 22 #include <stdio.h>
23 #include <string.h> 23 #ifdef HAVE_STRING_H
24 #ifdef HAVE_STRINGS_H 24 # include <string.h>
25 #else
25 # include <strings.h> 26 # include <strings.h>
26 #endif 27 #endif
27 28
28 #include <mailutils/sys/pop3.h> 29 #include <mailutils/sys/pop3.h>
29 30
30 int 31 static int
31 pop3_stat (pop3_t pop3, unsigned *msg_count, size_t *size) 32 pop3_stat0 (pop3_t pop3, unsigned *msg_count, size_t *size)
32 { 33 {
33 int status = 0; 34 int status;
34
35 if (pop3 == NULL)
36 return MU_ERROR_INVALID_PARAMETER;
37 35
38 switch (pop3->state) 36 switch (pop3->state)
39 { 37 {
...@@ -73,3 +71,19 @@ pop3_stat (pop3_t pop3, unsigned *msg_count, size_t *size) ...@@ -73,3 +71,19 @@ pop3_stat (pop3_t pop3, unsigned *msg_count, size_t *size)
73 71
74 return status; 72 return status;
75 } 73 }
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 }
......
...@@ -119,6 +119,7 @@ pop3_stream_create (pop3_t pop3, stream_t *pstream) ...@@ -119,6 +119,7 @@ pop3_stream_create (pop3_t pop3, stream_t *pstream)
119 p_stream->ref = 1; 119 p_stream->ref = 1;
120 p_stream->done = 0; 120 p_stream->done = 0;
121 p_stream->pop3 = pop3; 121 p_stream->pop3 = pop3;
122 monitor_create (&p_stream->lock);
122 *pstream = &p_stream->base; 123 *pstream = &p_stream->base;
123 return 0; 124 return 0;
124 } 125 }
...@@ -127,35 +128,50 @@ static int ...@@ -127,35 +128,50 @@ static int
127 p_add_ref (stream_t stream) 128 p_add_ref (stream_t stream)
128 { 129 {
129 struct p_stream *p_stream = (struct p_stream *)stream; 130 struct p_stream *p_stream = (struct p_stream *)stream;
130 return ++p_stream->ref; 131 int status = 0;
132 if (p_stream)
133 {
134 monitor_lock (p_stream->lock);
135 status = ++p_stream->ref;
136 monitor_unlock (p_stream->lock);
137 }
138 return status;
131 } 139 }
132 140
133 static int 141 static int
134 p_release (stream_t stream) 142 p_release (stream_t stream)
135 { 143 {
136 struct p_stream *p_stream = (struct p_stream *)stream; 144 struct p_stream *p_stream = (struct p_stream *)stream;
137 if (--p_stream->ref == 0) 145 int status = 0;
146 if (p_stream)
138 { 147 {
139 p_destroy (stream); 148 monitor_lock (p_stream->lock);
140 return 0; 149 status = --p_stream->ref;
150 if (status <= 0)
151 p_destroy (stream);
152 monitor_unlock (p_stream->lock);
141 } 153 }
142 return p_stream->ref; 154 return status;
143 } 155 }
144 156
145 static int 157 static int
146 p_destroy (stream_t stream) 158 p_destroy (stream_t stream)
147 { 159 {
148 struct p_stream *p_stream = (struct p_stream *)stream; 160 struct p_stream *p_stream = (struct p_stream *)stream;
149 if (!p_stream->done) 161 if (p_stream)
150 { 162 {
151 char buf[128]; 163 if (!p_stream->done)
152 size_t n = 0; 164 {
153 while (pop3_readline (p_stream->pop3, buf, sizeof buf, &n) > 0 165 char buf[128];
154 && n > 0) 166 size_t n = 0;
155 n = 0; 167 while (pop3_readline (p_stream->pop3, buf, sizeof buf, &n) > 0
168 && n > 0)
169 n = 0;
170 }
171 p_stream->pop3->state = POP3_NO_STATE;
172 monitor_destroy (p_stream->lock);
173 free (p_stream);
156 } 174 }
157 p_stream->pop3->state = POP3_NO_STATE;
158 free (stream);
159 return 0; 175 return 0;
160 } 176 }
161 177
...@@ -180,40 +196,45 @@ p_read (stream_t stream, char *buf, size_t buflen, size_t *pn) ...@@ -180,40 +196,45 @@ p_read (stream_t stream, char *buf, size_t buflen, size_t *pn)
180 struct p_stream *p_stream = (struct p_stream *)stream; 196 struct p_stream *p_stream = (struct p_stream *)stream;
181 size_t n = 0; 197 size_t n = 0;
182 int status = 0; 198 int status = 0;
183 if (!p_stream->done) 199 if (p_stream)
184 { 200 {
185 do 201 monitor_lock (p_stream->lock);
202 if (!p_stream->done)
186 { 203 {
187 size_t nread = 0; 204 do
188
189 /* The pop3_readline () function will always read one less to
190 be able to terminate the buffer, this will cause serious grief
191 for stream_read() where it is legitimate to have a buffer of
192 1 char. So we must catch here or change the behavoiour of
193 XXX_readline. */
194 if (buflen == 1)
195 { 205 {
196 char buffer[2]; 206 size_t nread = 0;
197 *buffer = '\0'; 207
198 status = pop3_readline (p_stream->pop3, buffer, 2, &nread); 208 /* The pop3_readline () function will always read one less to
199 *buf = *buffer; 209 be able to terminate the buffer, this will cause serious grief
210 for stream_read() where it is legitimate to have a buffer of
211 1 char. So we must catch here or change the behavoiour of
212 XXX_readline. */
213 if (buflen == 1)
214 {
215 char buffer[2];
216 *buffer = '\0';
217 status = pop3_readline (p_stream->pop3, buffer, 2, &nread);
218 *buf = *buffer;
219 }
220 else
221 status = pop3_readline (p_stream->pop3, buf, buflen, &nread);
222
223 if (status != 0)
224 break;
225 if (nread == 0)
226 {
227 p_stream->pop3->state = POP3_NO_STATE;
228 p_stream->done = 1;
229 break;
230 }
231 n += nread;
232 buflen -= nread;
233 buf += nread;
200 } 234 }
201 else 235 while (buflen > 0);
202 status = pop3_readline (p_stream->pop3, buf, buflen, &nread);
203
204 if (status != 0)
205 break;
206 if (nread == 0)
207 {
208 p_stream->pop3->state = POP3_NO_STATE;
209 p_stream->done = 1;
210 break;
211 }
212 n += nread;
213 buflen -= nread;
214 buf += nread;
215 } 236 }
216 while (buflen > 0); 237 monitor_unlock (p_stream->lock);
217 } 238 }
218 if (pn) 239 if (pn)
219 *pn = n; 240 *pn = n;
...@@ -226,14 +247,19 @@ p_readline (stream_t stream, char *buf, size_t buflen, size_t *pn) ...@@ -226,14 +247,19 @@ p_readline (stream_t stream, char *buf, size_t buflen, size_t *pn)
226 struct p_stream *p_stream = (struct p_stream *)stream; 247 struct p_stream *p_stream = (struct p_stream *)stream;
227 size_t n = 0; 248 size_t n = 0;
228 int status = 0; 249 int status = 0;
229 if (!p_stream->done) 250 if (p_stream)
230 { 251 {
231 status = pop3_readline (p_stream->pop3, buf, buflen, &n); 252 monitor_lock (p_stream->lock);
232 if (n == 0) 253 if (!p_stream->done)
233 { 254 {
234 p_stream->pop3->state = POP3_NO_STATE; 255 status = pop3_readline (p_stream->pop3, buf, buflen, &n);
235 p_stream->done = 1; 256 if (n == 0)
257 {
258 p_stream->pop3->state = POP3_NO_STATE;
259 p_stream->done = 1;
260 }
236 } 261 }
262 monitor_unlock (p_stream->lock);
237 } 263 }
238 if (pn) 264 if (pn)
239 *pn = n; 265 *pn = n;
......
...@@ -19,20 +19,18 @@ ...@@ -19,20 +19,18 @@
19 # include <config.h> 19 # include <config.h>
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #ifdef HAVE_STRING_H
23 #ifdef HAVE_STRINGS_H 23 # include <string.h>
24 #else
24 # include <strings.h> 25 # include <strings.h>
25 #endif 26 #endif
26 27
27 #include <mailutils/sys/pop3.h> 28 #include <mailutils/sys/pop3.h>
28 29
29 int 30 static int
30 pop3_top (pop3_t pop3, unsigned msgno, size_t lines, stream_t *pstream) 31 pop3_top0 (pop3_t pop3, unsigned msgno, size_t lines, stream_t *pstream)
31 { 32 {
32 int status = 0; 33 int status;
33
34 if (pop3 == NULL)
35 return MU_ERROR_INVALID_PARAMETER;
36 34
37 switch (pop3->state) 35 switch (pop3->state)
38 { 36 {
...@@ -71,3 +69,19 @@ pop3_top (pop3_t pop3, unsigned msgno, size_t lines, stream_t *pstream) ...@@ -71,3 +69,19 @@ pop3_top (pop3_t pop3, unsigned msgno, size_t lines, stream_t *pstream)
71 69
72 return status; 70 return status;
73 } 71 }
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 }
......
...@@ -19,21 +19,19 @@ ...@@ -19,21 +19,19 @@
19 # include <config.h> 19 # include <config.h>
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #ifdef HAVE_STRING_H
23 #ifdef HAVE_STRINGS_H 23 # include <string.h>
24 #else
24 # include <strings.h> 25 # include <strings.h>
25 #endif 26 #endif
26 27
27 #include <stdlib.h> 28 #include <stdlib.h>
28 #include <mailutils/sys/pop3.h> 29 #include <mailutils/sys/pop3.h>
29 30
30 int 31 static int
31 pop3_uidl (pop3_t pop3, unsigned msgno, char **uidl) 32 pop3_uidl0 (pop3_t pop3, unsigned msgno, char **uidl)
32 { 33 {
33 int status = 0; 34 int status;
34
35 if (pop3 == NULL)
36 return MU_ERROR_INVALID_PARAMETER;
37 35
38 switch (pop3->state) 36 switch (pop3->state)
39 { 37 {
...@@ -100,3 +98,19 @@ pop3_uidl (pop3_t pop3, unsigned msgno, char **uidl) ...@@ -100,3 +98,19 @@ pop3_uidl (pop3_t pop3, unsigned msgno, char **uidl)
100 98
101 return status; 99 return status;
102 } 100 }
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 }
......
...@@ -19,21 +19,19 @@ ...@@ -19,21 +19,19 @@
19 # include <config.h> 19 # include <config.h>
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #ifdef HAVE_STRING_H
23 #ifdef HAVE_STRINGS_H 23 # include <string.h>
24 #else
24 # include <strings.h> 25 # include <strings.h>
25 #endif 26 #endif
26 27
27 #include <stdlib.h> 28 #include <stdlib.h>
28 #include <mailutils/sys/pop3.h> 29 #include <mailutils/sys/pop3.h>
29 30
30 int 31 static int
31 pop3_uidl_all (pop3_t pop3, iterator_t *piterator) 32 pop3_uidl_all0 (pop3_t pop3, iterator_t *piterator)
32 { 33 {
33 int status = 0; 34 int status;
34
35 if (pop3 == NULL)
36 return MU_ERROR_INVALID_PARAMETER;
37 35
38 switch (pop3->state) 36 switch (pop3->state)
39 { 37 {
...@@ -72,3 +70,19 @@ pop3_uidl_all (pop3_t pop3, iterator_t *piterator) ...@@ -72,3 +70,19 @@ pop3_uidl_all (pop3_t pop3, iterator_t *piterator)
72 70
73 return status; 71 return status;
74 } 72 }
73
74 int
75 pop3_uidl_all (pop3_t pop3, iterator_t *piterator)
76 {
77 int status;
78
79 if (pop3 == NULL)
80 return MU_ERROR_INVALID_PARAMETER;
81
82 monitor_lock (pop3->lock);
83 monitor_cleanup_push (pop3_cleanup, pop3);
84 status = pop3_uidl_all0 (pop3, piterator);
85 monitor_unlock (pop3->lock);
86 monitor_cleanup_pop (0);
87 return status;
88 }
......
...@@ -19,20 +19,18 @@ ...@@ -19,20 +19,18 @@
19 # include <config.h> 19 # include <config.h>
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #ifdef HAVE_STRING_H
23 #ifdef HAVE_STRINGS_H 23 # include <string.h>
24 #else
24 # include <strings.h> 25 # include <strings.h>
25 #endif 26 #endif
26 27
27 #include <mailutils/sys/pop3.h> 28 #include <mailutils/sys/pop3.h>
28 29
29 int 30 static int
30 pop3_user (pop3_t pop3, const char *user) 31 pop3_user0 (pop3_t pop3, const char *user)
31 { 32 {
32 int status = 0; 33 int status;
33
34 if (pop3 == NULL)
35 return MU_ERROR_INVALID_PARAMETER;
36 34
37 switch (pop3->state) 35 switch (pop3->state)
38 { 36 {
...@@ -67,3 +65,19 @@ pop3_user (pop3_t pop3, const char *user) ...@@ -67,3 +65,19 @@ pop3_user (pop3_t pop3, const char *user)
67 65
68 return status; 66 return status;
69 } 67 }
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 }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
14 #include <strings.h> 14 #include <strings.h>
15 #include <stdlib.h> 15 #include <stdlib.h>
16 #include <termios.h> 16 #include <termios.h>
17 #include <signal.h>
17 18
18 #include <readline/readline.h> 19 #include <readline/readline.h>
19 #include <readline/history.h> 20 #include <readline/history.h>
...@@ -56,6 +57,8 @@ char *dupstr (const char *); ...@@ -56,6 +57,8 @@ char *dupstr (const char *);
56 int execute_line (char *); 57 int execute_line (char *);
57 int valid_argument (const char *, char *); 58 int valid_argument (const char *, char *);
58 59
60 void sig_int (int);
61
59 COMMAND commands[] = { 62 COMMAND commands[] = {
60 { "apop", com_apop, "Authenticate with APOP: APOP user secret" }, 63 { "apop", com_apop, "Authenticate with APOP: APOP user secret" },
61 { "disconnect", com_disconnect, "Close connection: disconnect" }, 64 { "disconnect", com_disconnect, "Close connection: disconnect" },
...@@ -121,6 +124,7 @@ main (int argc, char **argv) ...@@ -121,6 +124,7 @@ main (int argc, char **argv)
121 /* Loop reading and executing lines until the user quits. */ 124 /* Loop reading and executing lines until the user quits. */
122 for ( ; done == 0; ) 125 for ( ; done == 0; )
123 { 126 {
127
124 line = readline ("pop3> "); 128 line = readline ("pop3> ");
125 129
126 if (!line) 130 if (!line)
...@@ -354,9 +358,10 @@ com_uidl (char *arg) ...@@ -354,9 +358,10 @@ com_uidl (char *arg)
354 { 358 {
355 char *uidl = NULL; 359 char *uidl = NULL;
356 unsigned int msgno = strtoul (arg, NULL, 10); 360 unsigned int msgno = strtoul (arg, NULL, 10);
357 pop3_uidl (pop3, msgno, &uidl); 361 if (pop3_uidl (pop3, msgno, &uidl) == 0)
358 print_response (); 362 printf ("Msg: %d UIDL: %s\n", msgno, (uidl) ? uidl : "");
359 printf ("Msg: %d UIDL: %s\n", msgno, (uidl) ? uidl : ""); 363 else
364 print_response ();
360 } 365 }
361 return 0; 366 return 0;
362 } 367 }
...@@ -387,9 +392,10 @@ com_list (char *arg) ...@@ -387,9 +392,10 @@ com_list (char *arg)
387 { 392 {
388 size_t size = 0; 393 size_t size = 0;
389 unsigned int msgno = strtoul (arg, NULL, 10); 394 unsigned int msgno = strtoul (arg, NULL, 10);
390 pop3_list (pop3, msgno, &size); 395 if (pop3_list (pop3, msgno, &size) == 0)
391 print_response (); 396 printf ("Msg: %d Size: %d\n", msgno, size);
392 printf ("Msg: %d Size: %d\n", msgno, size); 397 else
398 print_response ();
393 } 399 }
394 return 0; 400 return 0;
395 } 401 }
...@@ -619,10 +625,19 @@ com_quit (char *arg) ...@@ -619,10 +625,19 @@ com_quit (char *arg)
619 (void)arg; 625 (void)arg;
620 if (pop3) 626 if (pop3)
621 { 627 {
622 pop3_quit (pop3); 628 if (pop3_quit (pop3) == 0)
623 pop3_disconnect (pop3); 629 {
624 print_response (); 630 print_response ();
631 pop3_disconnect (pop3);
632 }
633 else
634 {
635 print_response ();
636 fprintf (stdout, "Try 'exit' to leave %s\n", progname);
637 }
625 } 638 }
639 else
640 fprintf (stdout, "Try 'exit' to leave %s\n", progname);
626 return 0; 641 return 0;
627 } 642 }
628 643
......