summaryrefslogtreecommitdiffabout
authorzautrix <zautrix>2005-02-11 17:11:53 (UTC)
committer zautrix <zautrix>2005-02-11 17:11:53 (UTC)
commitd45d293d045a8d0f68e09ff9414e2dd6d18dd651 (patch) (unidiff)
tree9ea69affac4d35e8cb96074237702fb0b75e63ce
parent28b0fff54d5e3ddf59e922cae06285c3bdbbf1de (diff)
downloadkdepimpi-d45d293d045a8d0f68e09ff9414e2dd6d18dd651.zip
kdepimpi-d45d293d045a8d0f68e09ff9414e2dd6d18dd651.tar.gz
kdepimpi-d45d293d045a8d0f68e09ff9414e2dd6d18dd651.tar.bz2
fixi
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/generic/pop3driver.c9
-rw-r--r--kmicromail/libetpan/pop3/mailpop3.c5
-rw-r--r--kmicromail/libetpan/tools/mailstream_helper.c11
3 files changed, 19 insertions, 6 deletions
diff --git a/kmicromail/libetpan/generic/pop3driver.c b/kmicromail/libetpan/generic/pop3driver.c
index 375879e..475dfcc 100644
--- a/kmicromail/libetpan/generic/pop3driver.c
+++ b/kmicromail/libetpan/generic/pop3driver.c
@@ -1,388 +1,391 @@
1/* 1/*
2 * libEtPan! -- a mail stuff library 2 * libEtPan! -- a mail stuff library
3 * 3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa 4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its 15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived 16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission. 17 * from this software without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * $Id$ 33 * $Id$
34 */ 34 */
35 35
36#include "pop3driver.h" 36#include "pop3driver.h"
37 37
38#include <string.h> 38#include <string.h>
39#include <stdlib.h> 39#include <stdlib.h>
40 40
41#include "pop3driver_message.h" 41#include "pop3driver_message.h"
42#include "maildriver_tools.h" 42#include "maildriver_tools.h"
43#include "pop3driver_tools.h" 43#include "pop3driver_tools.h"
44#include "mailmessage.h" 44#include "mailmessage.h"
45 45
46static int pop3driver_initialize(mailsession * session); 46static int pop3driver_initialize(mailsession * session);
47 47
48static void pop3driver_uninitialize(mailsession * session); 48static void pop3driver_uninitialize(mailsession * session);
49 49
50static int pop3driver_parameters(mailsession * session, 50static int pop3driver_parameters(mailsession * session,
51 int id, void * value); 51 int id, void * value);
52 52
53static int pop3driver_connect_stream(mailsession * session, mailstream * s); 53static int pop3driver_connect_stream(mailsession * session, mailstream * s);
54 54
55static int pop3driver_starttls(mailsession * session); 55static int pop3driver_starttls(mailsession * session);
56 56
57static int pop3driver_login(mailsession * session, 57static int pop3driver_login(mailsession * session,
58 char * userid, char * password); 58 char * userid, char * password);
59 59
60static int pop3driver_logout(mailsession * session); 60static int pop3driver_logout(mailsession * session);
61 61
62static int pop3driver_noop(mailsession * session); 62static int pop3driver_noop(mailsession * session);
63 63
64static int pop3driver_status_folder(mailsession * session, char * mb, 64static int pop3driver_status_folder(mailsession * session, char * mb,
65 uint32_t * result_messages, uint32_t * result_recent, 65 uint32_t * result_messages, uint32_t * result_recent,
66 uint32_t * result_unseen); 66 uint32_t * result_unseen);
67 67
68static int pop3driver_messages_number(mailsession * session, char * mb, 68static int pop3driver_messages_number(mailsession * session, char * mb,
69 uint32_t * result); 69 uint32_t * result);
70 70
71static int pop3driver_remove_message(mailsession * session, uint32_t num); 71static int pop3driver_remove_message(mailsession * session, uint32_t num);
72 72
73static int pop3driver_get_messages_list(mailsession * session, 73static int pop3driver_get_messages_list(mailsession * session,
74 struct mailmessage_list ** result); 74 struct mailmessage_list ** result);
75 75
76static int pop3driver_get_message(mailsession * session, 76static int pop3driver_get_message(mailsession * session,
77 uint32_t num, mailmessage ** result); 77 uint32_t num, mailmessage ** result);
78 78
79static mailsession_driver local_pop3_session_driver = { 79static mailsession_driver local_pop3_session_driver = {
80 .sess_name = "pop3", 80 .sess_name = "pop3",
81 81
82 .sess_initialize = pop3driver_initialize, 82 .sess_initialize = pop3driver_initialize,
83 .sess_uninitialize = pop3driver_uninitialize, 83 .sess_uninitialize = pop3driver_uninitialize,
84 84
85 .sess_parameters = pop3driver_parameters, 85 .sess_parameters = pop3driver_parameters,
86 86
87 .sess_connect_stream = pop3driver_connect_stream, 87 .sess_connect_stream = pop3driver_connect_stream,
88 .sess_connect_path = NULL, 88 .sess_connect_path = NULL,
89 .sess_starttls = pop3driver_starttls, 89 .sess_starttls = pop3driver_starttls,
90 .sess_login = pop3driver_login, 90 .sess_login = pop3driver_login,
91 .sess_logout = pop3driver_logout, 91 .sess_logout = pop3driver_logout,
92 .sess_noop = pop3driver_noop, 92 .sess_noop = pop3driver_noop,
93 93
94 .sess_build_folder_name = NULL, 94 .sess_build_folder_name = NULL,
95 .sess_create_folder = NULL, 95 .sess_create_folder = NULL,
96 .sess_delete_folder = NULL, 96 .sess_delete_folder = NULL,
97 .sess_rename_folder = NULL, 97 .sess_rename_folder = NULL,
98 .sess_check_folder = NULL, 98 .sess_check_folder = NULL,
99 .sess_examine_folder = NULL, 99 .sess_examine_folder = NULL,
100 .sess_select_folder = NULL, 100 .sess_select_folder = NULL,
101 .sess_expunge_folder = NULL, 101 .sess_expunge_folder = NULL,
102 .sess_status_folder = pop3driver_status_folder, 102 .sess_status_folder = pop3driver_status_folder,
103 .sess_messages_number = pop3driver_messages_number, 103 .sess_messages_number = pop3driver_messages_number,
104 .sess_recent_number = pop3driver_messages_number, 104 .sess_recent_number = pop3driver_messages_number,
105 .sess_unseen_number = pop3driver_messages_number, 105 .sess_unseen_number = pop3driver_messages_number,
106 .sess_list_folders = NULL, 106 .sess_list_folders = NULL,
107 .sess_lsub_folders = NULL, 107 .sess_lsub_folders = NULL,
108 .sess_subscribe_folder = NULL, 108 .sess_subscribe_folder = NULL,
109 .sess_unsubscribe_folder = NULL, 109 .sess_unsubscribe_folder = NULL,
110 110
111 .sess_append_message = NULL, 111 .sess_append_message = NULL,
112 .sess_append_message_flags = NULL, 112 .sess_append_message_flags = NULL,
113 .sess_copy_message = NULL, 113 .sess_copy_message = NULL,
114 .sess_move_message = NULL, 114 .sess_move_message = NULL,
115 115
116 .sess_get_messages_list = pop3driver_get_messages_list, 116 .sess_get_messages_list = pop3driver_get_messages_list,
117 .sess_get_envelopes_list = maildriver_generic_get_envelopes_list, 117 .sess_get_envelopes_list = maildriver_generic_get_envelopes_list,
118 .sess_remove_message = pop3driver_remove_message, 118 .sess_remove_message = pop3driver_remove_message,
119#if 0 119#if 0
120 .sess_search_messages = maildriver_generic_search_messages, 120 .sess_search_messages = maildriver_generic_search_messages,
121#endif 121#endif
122 122
123 .sess_get_message = pop3driver_get_message, 123 .sess_get_message = pop3driver_get_message,
124 .sess_get_message_by_uid = NULL, 124 .sess_get_message_by_uid = NULL,
125}; 125};
126 126
127mailsession_driver * pop3_session_driver = &local_pop3_session_driver; 127mailsession_driver * pop3_session_driver = &local_pop3_session_driver;
128 128
129static inline struct pop3_session_state_data * 129static inline struct pop3_session_state_data *
130get_data(mailsession * session) 130get_data(mailsession * session)
131{ 131{
132 return session->sess_data; 132 return session->sess_data;
133} 133}
134 134
135static mailpop3 * get_pop3_session(mailsession * session) 135static mailpop3 * get_pop3_session(mailsession * session)
136{ 136{
137 return get_data(session)->pop3_session; 137 return get_data(session)->pop3_session;
138} 138}
139 139
140static int pop3driver_initialize(mailsession * session) 140static int pop3driver_initialize(mailsession * session)
141{ 141{
142 struct pop3_session_state_data * data; 142 struct pop3_session_state_data * data;
143 mailpop3 * pop3; 143 mailpop3 * pop3;
144 144
145 pop3 = mailpop3_new(0, NULL); 145 pop3 = mailpop3_new(0, NULL);
146 if (session == NULL) 146 if (session == NULL)
147 goto err; 147 goto err;
148 148
149 data = malloc(sizeof(* data)); 149 data = malloc(sizeof(* data));
150 if (data == NULL) 150 if (data == NULL)
151 goto free; 151 goto free;
152 152
153 data->pop3_session = pop3; 153 data->pop3_session = pop3;
154 data->pop3_auth_type = POP3DRIVER_AUTH_TYPE_PLAIN; 154 data->pop3_auth_type = POP3DRIVER_AUTH_TYPE_PLAIN;
155 155
156 session->sess_data = data; 156 session->sess_data = data;
157 157
158 return MAIL_NO_ERROR; 158 return MAIL_NO_ERROR;
159 159
160 free: 160 free:
161 mailpop3_free(pop3); 161 mailpop3_free(pop3);
162 err: 162 err:
163 return MAIL_ERROR_MEMORY; 163 return MAIL_ERROR_MEMORY;
164} 164}
165 165
166static void pop3driver_uninitialize(mailsession * session) 166static void pop3driver_uninitialize(mailsession * session)
167{ 167{
168 struct pop3_session_state_data * data; 168 struct pop3_session_state_data * data;
169 169
170 data = get_data(session); 170 data = get_data(session);
171 171
172 mailpop3_free(data->pop3_session); 172 mailpop3_free(data->pop3_session);
173 free(data); 173 free(data);
174 174
175 session->sess_data = data; 175 session->sess_data = data;
176} 176}
177 177
178static int pop3driver_connect_stream(mailsession * session, mailstream * s) 178static int pop3driver_connect_stream(mailsession * session, mailstream * s)
179{ 179{
180 int r; 180 int r;
181 181
182 r = mailpop3_connect(get_pop3_session(session), s); 182 r = mailpop3_connect(get_pop3_session(session), s);
183 183
184 switch (r) { 184 switch (r) {
185 case MAILPOP3_NO_ERROR: 185 case MAILPOP3_NO_ERROR:
186 return MAIL_NO_ERROR_NON_AUTHENTICATED; 186 return MAIL_NO_ERROR_NON_AUTHENTICATED;
187 187
188 default: 188 default:
189 return pop3driver_pop3_error_to_mail_error(r); 189 return pop3driver_pop3_error_to_mail_error(r);
190 } 190 }
191} 191}
192 192
193static int pop3driver_starttls(mailsession * session) 193static int pop3driver_starttls(mailsession * session)
194{ 194{
195 int r; 195 int r;
196 int fd; 196 int fd;
197 mailstream_low * low; 197 mailstream_low * low;
198 mailstream_low * new_low; 198 mailstream_low * new_low;
199 mailpop3 * pop3; 199 mailpop3 * pop3;
200 200
201 pop3 = get_pop3_session(session); 201 pop3 = get_pop3_session(session);
202 202
203 r = mailpop3_stls(pop3); 203 r = mailpop3_stls(pop3);
204 204
205 switch (r) { 205 switch (r) {
206 case MAILPOP3_NO_ERROR: 206 case MAILPOP3_NO_ERROR:
207 break; 207 break;
208 default: 208 default:
209 return pop3driver_pop3_error_to_mail_error(r); 209 return pop3driver_pop3_error_to_mail_error(r);
210 } 210 }
211 211
212 low = mailstream_get_low(pop3->pop3_stream); 212 low = mailstream_get_low(pop3->pop3_stream);
213 fd = mailstream_low_get_fd(low); 213 fd = mailstream_low_get_fd(low);
214 if (fd == -1) 214 if (fd == -1)
215 return MAIL_ERROR_STREAM; 215 return MAIL_ERROR_STREAM;
216 216
217 new_low = mailstream_low_ssl_open(fd); 217 new_low = mailstream_low_ssl_open(fd);
218 if (new_low == NULL) 218 if (new_low == NULL)
219 return MAIL_ERROR_STREAM; 219 return MAIL_ERROR_STREAM;
220 mailstream_low_free(low); 220 mailstream_low_free(low);
221 mailstream_set_low(pop3->pop3_stream, new_low); 221 mailstream_set_low(pop3->pop3_stream, new_low);
222 222
223 return MAIL_NO_ERROR; 223 return MAIL_NO_ERROR;
224} 224}
225 225
226static int pop3driver_parameters(mailsession * session, 226static int pop3driver_parameters(mailsession * session,
227 int id, void * value) 227 int id, void * value)
228{ 228{
229 struct pop3_session_state_data * data; 229 struct pop3_session_state_data * data;
230 230
231 data = get_data(session); 231 data = get_data(session);
232 232
233 switch (id) { 233 switch (id) {
234 case POP3DRIVER_SET_AUTH_TYPE: 234 case POP3DRIVER_SET_AUTH_TYPE:
235 { 235 {
236 int * param; 236 int * param;
237 237
238 param = value; 238 param = value;
239 239
240 data->pop3_auth_type = * param; 240 data->pop3_auth_type = * param;
241 return MAIL_NO_ERROR; 241 return MAIL_NO_ERROR;
242 } 242 }
243 } 243 }
244 244
245 return MAIL_ERROR_INVAL; 245 return MAIL_ERROR_INVAL;
246} 246}
247 247
248static int pop3driver_login(mailsession * session, 248static int pop3driver_login(mailsession * session,
249 char * userid, char * password) 249 char * userid, char * password)
250{ 250{
251 int r; 251 int r;
252 carray * msg_tab; 252 carray * msg_tab;
253 struct pop3_session_state_data * data; 253 struct pop3_session_state_data * data;
254 254
255 data = get_data(session); 255 data = get_data(session);
256 256
257 switch (data->pop3_auth_type) { 257 switch (data->pop3_auth_type) {
258 case POP3DRIVER_AUTH_TYPE_TRY_APOP: 258 case POP3DRIVER_AUTH_TYPE_TRY_APOP:
259 r = mailpop3_login_apop(get_pop3_session(session), userid, password); 259 r = mailpop3_login_apop(get_pop3_session(session), userid, password);
260 if (r != MAILPOP3_NO_ERROR) 260 if (r != MAILPOP3_NO_ERROR)
261 r = mailpop3_login(get_pop3_session(session), userid, password); 261 r = mailpop3_login(get_pop3_session(session), userid, password);
262 break; 262 break;
263 263
264 case POP3DRIVER_AUTH_TYPE_APOP: 264 case POP3DRIVER_AUTH_TYPE_APOP:
265 r = mailpop3_login_apop(get_pop3_session(session), userid, password); 265 r = mailpop3_login_apop(get_pop3_session(session), userid, password);
266 break; 266 break;
267 267
268 default: 268 default:
269 case POP3DRIVER_AUTH_TYPE_PLAIN: 269 case POP3DRIVER_AUTH_TYPE_PLAIN:
270 r = mailpop3_login(get_pop3_session(session), userid, password); 270 r = mailpop3_login(get_pop3_session(session), userid, password);
271 break; 271 break;
272 } 272 }
273 // LR 2 lines
274 int ret = pop3driver_pop3_error_to_mail_error(r);
275 if ( ret == MAIL_NO_ERROR )
276 mailpop3_list(get_pop3_session(session), &msg_tab);
273 277
274 mailpop3_list(get_pop3_session(session), &msg_tab); 278 // LR
275 279 return ret;
276 return pop3driver_pop3_error_to_mail_error(r);
277} 280}
278 281
279static int pop3driver_logout(mailsession * session) 282static int pop3driver_logout(mailsession * session)
280{ 283{
281 int r; 284 int r;
282 285
283 r = mailpop3_quit(get_pop3_session(session)); 286 r = mailpop3_quit(get_pop3_session(session));
284 287
285 return pop3driver_pop3_error_to_mail_error(r); 288 return pop3driver_pop3_error_to_mail_error(r);
286} 289}
287 290
288static int pop3driver_noop(mailsession * session) 291static int pop3driver_noop(mailsession * session)
289{ 292{
290 int r; 293 int r;
291 294
292 r = mailpop3_noop(get_pop3_session(session)); 295 r = mailpop3_noop(get_pop3_session(session));
293 296
294 return pop3driver_pop3_error_to_mail_error(r); 297 return pop3driver_pop3_error_to_mail_error(r);
295} 298}
296 299
297static int pop3driver_status_folder(mailsession * session, char * mb, 300static int pop3driver_status_folder(mailsession * session, char * mb,
298 uint32_t * result_messages, 301 uint32_t * result_messages,
299 uint32_t * result_recent, 302 uint32_t * result_recent,
300 uint32_t * result_unseen) 303 uint32_t * result_unseen)
301{ 304{
302 uint32_t count; 305 uint32_t count;
303 int r; 306 int r;
304 307
305 r = pop3driver_messages_number(session, mb, &count); 308 r = pop3driver_messages_number(session, mb, &count);
306 if (r != MAIL_NO_ERROR) 309 if (r != MAIL_NO_ERROR)
307 return r; 310 return r;
308 311
309 * result_messages = count; 312 * result_messages = count;
310 * result_recent = count; 313 * result_recent = count;
311 * result_unseen = count; 314 * result_unseen = count;
312 315
313 return MAIL_NO_ERROR; 316 return MAIL_NO_ERROR;
314} 317}
315 318
316static int pop3driver_messages_number(mailsession * session, char * mb, 319static int pop3driver_messages_number(mailsession * session, char * mb,
317 uint32_t * result) 320 uint32_t * result)
318{ 321{
319 carray * msg_tab; 322 carray * msg_tab;
320 323
321 mailpop3_list(get_pop3_session(session), &msg_tab); 324 mailpop3_list(get_pop3_session(session), &msg_tab);
322 325
323 * result = carray_count(msg_tab) - 326 * result = carray_count(msg_tab) -
324 get_pop3_session(session)->pop3_deleted_count; 327 get_pop3_session(session)->pop3_deleted_count;
325 328
326 return MAIL_NO_ERROR; 329 return MAIL_NO_ERROR;
327} 330}
328 331
329 332
330/* messages operations */ 333/* messages operations */
331 334
332static int pop3driver_remove_message(mailsession * session, uint32_t num) 335static int pop3driver_remove_message(mailsession * session, uint32_t num)
333{ 336{
334 mailpop3 * pop3; 337 mailpop3 * pop3;
335 int r; 338 int r;
336 339
337 pop3 = get_pop3_session(session); 340 pop3 = get_pop3_session(session);
338 341
339 r = mailpop3_dele(pop3, num); 342 r = mailpop3_dele(pop3, num);
340 switch (r) { 343 switch (r) {
341 case MAILPOP3_ERROR_BAD_STATE: 344 case MAILPOP3_ERROR_BAD_STATE:
342 return MAIL_ERROR_BAD_STATE; 345 return MAIL_ERROR_BAD_STATE;
343 346
344 case MAILPOP3_ERROR_NO_SUCH_MESSAGE: 347 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
345 return MAIL_ERROR_MSG_NOT_FOUND; 348 return MAIL_ERROR_MSG_NOT_FOUND;
346 349
347 case MAILPOP3_ERROR_STREAM: 350 case MAILPOP3_ERROR_STREAM:
348 return MAIL_ERROR_STREAM; 351 return MAIL_ERROR_STREAM;
349 352
350 case MAILPOP3_NO_ERROR: 353 case MAILPOP3_NO_ERROR:
351 return MAIL_NO_ERROR; 354 return MAIL_NO_ERROR;
352 355
353 default: 356 default:
354 return MAIL_ERROR_REMOVE; 357 return MAIL_ERROR_REMOVE;
355 } 358 }
356} 359}
357 360
358static int pop3driver_get_messages_list(mailsession * session, 361static int pop3driver_get_messages_list(mailsession * session,
359 struct mailmessage_list ** result) 362 struct mailmessage_list ** result)
360{ 363{
361 mailpop3 * pop3; 364 mailpop3 * pop3;
362 365
363 pop3 = get_pop3_session(session); 366 pop3 = get_pop3_session(session);
364 367
365 return pop3_get_messages_list(pop3, session, 368 return pop3_get_messages_list(pop3, session,
366 pop3_message_driver, result); 369 pop3_message_driver, result);
367} 370}
368 371
369static int pop3driver_get_message(mailsession * session, 372static int pop3driver_get_message(mailsession * session,
370 uint32_t num, mailmessage ** result) 373 uint32_t num, mailmessage ** result)
371{ 374{
372 mailmessage * msg_info; 375 mailmessage * msg_info;
373 int r; 376 int r;
374 377
375 msg_info = mailmessage_new(); 378 msg_info = mailmessage_new();
376 if (msg_info == NULL) 379 if (msg_info == NULL)
377 return MAIL_ERROR_MEMORY; 380 return MAIL_ERROR_MEMORY;
378 381
379 r = mailmessage_init(msg_info, session, pop3_message_driver, num, 0); 382 r = mailmessage_init(msg_info, session, pop3_message_driver, num, 0);
380 if (r != MAIL_NO_ERROR) { 383 if (r != MAIL_NO_ERROR) {
381 mailmessage_free(msg_info); 384 mailmessage_free(msg_info);
382 return r; 385 return r;
383 } 386 }
384 387
385 * result = msg_info; 388 * result = msg_info;
386 389
387 return MAIL_NO_ERROR; 390 return MAIL_NO_ERROR;
388} 391}
diff --git a/kmicromail/libetpan/pop3/mailpop3.c b/kmicromail/libetpan/pop3/mailpop3.c
index 28fafe9..691b07a 100644
--- a/kmicromail/libetpan/pop3/mailpop3.c
+++ b/kmicromail/libetpan/pop3/mailpop3.c
@@ -1,1024 +1,1027 @@
1/* 1/*
2 * libEtPan! -- a mail stuff library 2 * libEtPan! -- a mail stuff library
3 * 3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa 4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its 15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived 16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission. 17 * from this software without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * $Id$ 33 * $Id$
34 */ 34 */
35 35
36/* 36/*
37 POP3 Protocol 37 POP3 Protocol
38 38
39 RFC 1734 39 RFC 1734
40 RFC 1939 40 RFC 1939
41 RFC 2449 41 RFC 2449
42 42
43 */ 43 */
44 44
45#include "mailpop3.h" 45#include "mailpop3.h"
46#include <stdio.h> 46#include <stdio.h>
47#include <string.h> 47#include <string.h>
48#include "md5.h" 48#include "md5.h"
49#include "mail.h" 49#include "mail.h"
50#include <stdlib.h> 50#include <stdlib.h>
51 51
52 52
53 53
54 54
55enum { 55enum {
56 POP3_STATE_DISCONNECTED, 56 POP3_STATE_DISCONNECTED,
57 POP3_STATE_AUTHORIZATION, 57 POP3_STATE_AUTHORIZATION,
58 POP3_STATE_TRANSACTION 58 POP3_STATE_TRANSACTION
59}; 59};
60 60
61 61
62 62
63/* 63/*
64 mailpop3_msg_info structure 64 mailpop3_msg_info structure
65*/ 65*/
66 66
67static struct mailpop3_msg_info * 67static struct mailpop3_msg_info *
68mailpop3_msg_info_new(unsigned int index, uint32_t size, char * uidl) 68mailpop3_msg_info_new(unsigned int index, uint32_t size, char * uidl)
69{ 69{
70 struct mailpop3_msg_info * msg; 70 struct mailpop3_msg_info * msg;
71 71
72 msg = malloc(sizeof(* msg)); 72 msg = malloc(sizeof(* msg));
73 if (msg == NULL) 73 if (msg == NULL)
74 return NULL; 74 return NULL;
75 msg->msg_index = index; 75 msg->msg_index = index;
76 msg->msg_size = size; 76 msg->msg_size = size;
77 msg->msg_deleted = FALSE; 77 msg->msg_deleted = FALSE;
78 msg->msg_uidl = uidl; 78 msg->msg_uidl = uidl;
79 79
80 return msg; 80 return msg;
81} 81}
82 82
83static void mailpop3_msg_info_free(struct mailpop3_msg_info * msg) 83static void mailpop3_msg_info_free(struct mailpop3_msg_info * msg)
84{ 84{
85 if (msg->msg_uidl != NULL) 85 if (msg->msg_uidl != NULL)
86 free(msg->msg_uidl); 86 free(msg->msg_uidl);
87 free(msg); 87 free(msg);
88} 88}
89 89
90static void mailpop3_msg_info_tab_free(carray * msg_tab) 90static void mailpop3_msg_info_tab_free(carray * msg_tab)
91{ 91{
92 unsigned int i; 92 unsigned int i;
93 93
94 for(i = 0 ; i < carray_count(msg_tab) ; i++) { 94 for(i = 0 ; i < carray_count(msg_tab) ; i++) {
95 struct mailpop3_msg_info * msg; 95 struct mailpop3_msg_info * msg;
96 96
97 msg = carray_get(msg_tab, i); 97 msg = carray_get(msg_tab, i);
98 mailpop3_msg_info_free(msg); 98 mailpop3_msg_info_free(msg);
99 } 99 }
100 carray_free(msg_tab); 100 carray_free(msg_tab);
101} 101}
102 102
103static void mailpop3_msg_info_tab_reset(carray * msg_tab) 103static void mailpop3_msg_info_tab_reset(carray * msg_tab)
104{ 104{
105 unsigned int i; 105 unsigned int i;
106 106
107 for(i = 0 ; i < carray_count(msg_tab) ; i++) { 107 for(i = 0 ; i < carray_count(msg_tab) ; i++) {
108 struct mailpop3_msg_info * msg; 108 struct mailpop3_msg_info * msg;
109 msg = carray_get(msg_tab, i); 109 msg = carray_get(msg_tab, i);
110 msg->msg_deleted = FALSE; 110 msg->msg_deleted = FALSE;
111 } 111 }
112} 112}
113 113
114static inline struct mailpop3_msg_info * 114static inline struct mailpop3_msg_info *
115mailpop3_msg_info_tab_find_msg(carray * msg_tab, unsigned int index) 115mailpop3_msg_info_tab_find_msg(carray * msg_tab, unsigned int index)
116{ 116{
117 struct mailpop3_msg_info * msg; 117 struct mailpop3_msg_info * msg;
118 118
119 if (index == 0) 119 if (index == 0)
120 return NULL; 120 return NULL;
121 121
122 if (index > carray_count(msg_tab)) 122 if (index > carray_count(msg_tab))
123 return NULL; 123 return NULL;
124 124
125 msg = carray_get(msg_tab, index - 1); 125 msg = carray_get(msg_tab, index - 1);
126 126
127 return msg; 127 return msg;
128} 128}
129 129
130 130
131 131
132int mailpop3_get_msg_info(mailpop3 * f, unsigned int index, 132int mailpop3_get_msg_info(mailpop3 * f, unsigned int index,
133 struct mailpop3_msg_info ** result) 133 struct mailpop3_msg_info ** result)
134{ 134{
135 carray * tab; 135 carray * tab;
136 struct mailpop3_msg_info * info; 136 struct mailpop3_msg_info * info;
137 137
138 mailpop3_list(f, &tab); 138 mailpop3_list(f, &tab);
139 139
140 if (tab == NULL) 140 if (tab == NULL)
141 return MAILPOP3_ERROR_BAD_STATE; 141 return MAILPOP3_ERROR_BAD_STATE;
142 142
143 info = mailpop3_msg_info_tab_find_msg(tab, index); 143 info = mailpop3_msg_info_tab_find_msg(tab, index);
144 if (info == NULL) 144 if (info == NULL)
145 return MAILPOP3_ERROR_NO_SUCH_MESSAGE; 145 return MAILPOP3_ERROR_NO_SUCH_MESSAGE;
146 146
147 * result = info; 147 * result = info;
148 148
149 return MAILPOP3_NO_ERROR; 149 return MAILPOP3_NO_ERROR;
150} 150}
151 151
152 152
153/* 153/*
154 mailpop3_capa 154 mailpop3_capa
155*/ 155*/
156 156
157struct mailpop3_capa * mailpop3_capa_new(char * name, clist * param) 157struct mailpop3_capa * mailpop3_capa_new(char * name, clist * param)
158{ 158{
159 struct mailpop3_capa * capa; 159 struct mailpop3_capa * capa;
160 160
161 capa = malloc(sizeof(* capa)); 161 capa = malloc(sizeof(* capa));
162 if (capa == NULL) 162 if (capa == NULL)
163 return NULL; 163 return NULL;
164 capa->cap_name = name; 164 capa->cap_name = name;
165 capa->cap_param = param; 165 capa->cap_param = param;
166 166
167 return capa; 167 return capa;
168} 168}
169 169
170 170
171void mailpop3_capa_free(struct mailpop3_capa * capa) 171void mailpop3_capa_free(struct mailpop3_capa * capa)
172{ 172{
173 clist_foreach(capa->cap_param, (clist_func) free, NULL); 173 clist_foreach(capa->cap_param, (clist_func) free, NULL);
174 clist_free(capa->cap_param); 174 clist_free(capa->cap_param);
175 free(capa->cap_name); 175 free(capa->cap_name);
176 free(capa); 176 free(capa);
177} 177}
178 178
179/* 179/*
180 mailpop3 structure 180 mailpop3 structure
181*/ 181*/
182 182
183mailpop3 * mailpop3_new(size_t progr_rate, progress_function * progr_fun) 183mailpop3 * mailpop3_new(size_t progr_rate, progress_function * progr_fun)
184{ 184{
185 mailpop3 * f; 185 mailpop3 * f;
186 186
187 f = malloc(sizeof(* f)); 187 f = malloc(sizeof(* f));
188 if (f == NULL) 188 if (f == NULL)
189 goto err; 189 goto err;
190 190
191 f->pop3_timestamp = NULL; 191 f->pop3_timestamp = NULL;
192 f->pop3_response = NULL; 192 f->pop3_response = NULL;
193 193
194 f->pop3_stream = NULL; 194 f->pop3_stream = NULL;
195 195
196 f->pop3_progr_rate = progr_rate; 196 f->pop3_progr_rate = progr_rate;
197 f->pop3_progr_fun = progr_fun; 197 f->pop3_progr_fun = progr_fun;
198 198
199 f->pop3_stream_buffer = mmap_string_new(""); 199 f->pop3_stream_buffer = mmap_string_new("");
200 if (f->pop3_stream_buffer == NULL) 200 if (f->pop3_stream_buffer == NULL)
201 goto free_f; 201 goto free_f;
202 202
203 f->pop3_response_buffer = mmap_string_new(""); 203 f->pop3_response_buffer = mmap_string_new("");
204 if (f->pop3_response_buffer == NULL) 204 if (f->pop3_response_buffer == NULL)
205 goto free_stream_buffer; 205 goto free_stream_buffer;
206 206
207 f->pop3_msg_tab = NULL; 207 f->pop3_msg_tab = NULL;
208 f->pop3_deleted_count = 0; 208 f->pop3_deleted_count = 0;
209 f->pop3_state = POP3_STATE_DISCONNECTED; 209 f->pop3_state = POP3_STATE_DISCONNECTED;
210 210
211 return f; 211 return f;
212 212
213 free_stream_buffer: 213 free_stream_buffer:
214 mmap_string_free(f->pop3_stream_buffer); 214 mmap_string_free(f->pop3_stream_buffer);
215 free_f: 215 free_f:
216 free(f); 216 free(f);
217 err: 217 err:
218 return NULL; 218 return NULL;
219} 219}
220 220
221 221
222 222
223void mailpop3_free(mailpop3 * f) 223void mailpop3_free(mailpop3 * f)
224{ 224{
225 if (f->pop3_stream) 225 if (f->pop3_stream)
226 mailpop3_quit(f); 226 mailpop3_quit(f);
227 227
228 mmap_string_free(f->pop3_response_buffer); 228 mmap_string_free(f->pop3_response_buffer);
229 mmap_string_free(f->pop3_stream_buffer); 229 mmap_string_free(f->pop3_stream_buffer);
230 230
231 free(f); 231 free(f);
232} 232}
233 233
234 234
235 235
236 236
237 237
238 238
239 239
240 240
241 241
242 242
243 243
244/* 244/*
245 operations on mailpop3 structure 245 operations on mailpop3 structure
246*/ 246*/
247 247
248#define RESPONSE_OK 0 248#define RESPONSE_OK 0
249#define RESPONSE_ERR -1 249#define RESPONSE_ERR -1
250 250
251static int send_command(mailpop3 * f, char * command); 251static int send_command(mailpop3 * f, char * command);
252 252
253static char * read_line(mailpop3 * f); 253static char * read_line(mailpop3 * f);
254 254
255static char * read_multiline(mailpop3 * f, size_t size, 255static char * read_multiline(mailpop3 * f, size_t size,
256 MMAPString * multiline_buffer); 256 MMAPString * multiline_buffer);
257 257
258static int parse_response(mailpop3 * f, char * response); 258static int parse_response(mailpop3 * f, char * response);
259 259
260 260
261/* get the timestamp in the connection response */ 261/* get the timestamp in the connection response */
262 262
263#define TIMESTAMP_START '<' 263#define TIMESTAMP_START '<'
264#define TIMESTAMP_END '>' 264#define TIMESTAMP_END '>'
265 265
266static char * mailpop3_get_timestamp(char * response) 266static char * mailpop3_get_timestamp(char * response)
267{ 267{
268 char * begin_timestamp; 268 char * begin_timestamp;
269 char * end_timestamp; 269 char * end_timestamp;
270 char * timestamp; 270 char * timestamp;
271 int len_timestamp; 271 int len_timestamp;
272 272
273 if (response == NULL) 273 if (response == NULL)
274 return NULL; 274 return NULL;
275 275
276 begin_timestamp = strchr(response, TIMESTAMP_START); 276 begin_timestamp = strchr(response, TIMESTAMP_START);
277 277
278 end_timestamp = NULL; 278 end_timestamp = NULL;
279 if (begin_timestamp != NULL) { 279 if (begin_timestamp != NULL) {
280 end_timestamp = strchr(begin_timestamp, TIMESTAMP_END); 280 end_timestamp = strchr(begin_timestamp, TIMESTAMP_END);
281 if (end_timestamp == NULL) 281 if (end_timestamp == NULL)
282 begin_timestamp = NULL; 282 begin_timestamp = NULL;
283 } 283 }
284 284
285 if (!begin_timestamp) 285 if (!begin_timestamp)
286 return NULL; 286 return NULL;
287 287
288 len_timestamp = end_timestamp - begin_timestamp + 1; 288 len_timestamp = end_timestamp - begin_timestamp + 1;
289 289
290 timestamp = malloc(len_timestamp + 1); 290 timestamp = malloc(len_timestamp + 1);
291 if (timestamp == NULL) 291 if (timestamp == NULL)
292 return NULL; 292 return NULL;
293 strncpy(timestamp, begin_timestamp, len_timestamp); 293 strncpy(timestamp, begin_timestamp, len_timestamp);
294 timestamp[len_timestamp] = '\0'; 294 timestamp[len_timestamp] = '\0';
295 295
296 return timestamp; 296 return timestamp;
297} 297}
298 298
299/* 299/*
300 connect a stream to the mailpop3 structure 300 connect a stream to the mailpop3 structure
301*/ 301*/
302 302
303int mailpop3_connect(mailpop3 * f, mailstream * s) 303int mailpop3_connect(mailpop3 * f, mailstream * s)
304{ 304{
305 char * response; 305 char * response;
306 int r; 306 int r;
307 char * timestamp; 307 char * timestamp;
308 308
309 if (f->pop3_state != POP3_STATE_DISCONNECTED) 309 if (f->pop3_state != POP3_STATE_DISCONNECTED)
310 return MAILPOP3_ERROR_BAD_STATE; 310 return MAILPOP3_ERROR_BAD_STATE;
311 311
312 f->pop3_stream = s; 312 f->pop3_stream = s;
313 313
314 response = read_line(f); 314 response = read_line(f);
315 315
316 r = parse_response(f, response); 316 r = parse_response(f, response);
317 if (r != RESPONSE_OK) 317 if (r != RESPONSE_OK)
318 return MAILPOP3_ERROR_UNAUTHORIZED; 318 return MAILPOP3_ERROR_UNAUTHORIZED;
319 319
320 f->pop3_state = POP3_STATE_AUTHORIZATION; 320 f->pop3_state = POP3_STATE_AUTHORIZATION;
321 321
322 timestamp = mailpop3_get_timestamp(f->pop3_response); 322 timestamp = mailpop3_get_timestamp(f->pop3_response);
323 if (timestamp != NULL) 323 if (timestamp != NULL)
324 f->pop3_timestamp = timestamp; 324 f->pop3_timestamp = timestamp;
325 325
326 return MAILPOP3_NO_ERROR; 326 return MAILPOP3_NO_ERROR;
327} 327}
328 328
329 329
330/* 330/*
331 disconnect from a pop3 server 331 disconnect from a pop3 server
332*/ 332*/
333 333
334int mailpop3_quit(mailpop3 * f) 334int mailpop3_quit(mailpop3 * f)
335{ 335{
336 char command[POP3_STRING_SIZE]; 336 char command[POP3_STRING_SIZE];
337 char * response; 337 char * response;
338 int r; 338 int r;
339 int res; 339 int res;
340 340
341 if ((f->pop3_state != POP3_STATE_AUTHORIZATION) 341 if ((f->pop3_state != POP3_STATE_AUTHORIZATION)
342 && (f->pop3_state != POP3_STATE_TRANSACTION)) { 342 && (f->pop3_state != POP3_STATE_TRANSACTION)) {
343 res = MAILPOP3_ERROR_BAD_STATE; 343 res = MAILPOP3_ERROR_BAD_STATE;
344 goto close; 344 goto close;
345 } 345 }
346 346
347 snprintf(command, POP3_STRING_SIZE, "QUIT\r\n"); 347 snprintf(command, POP3_STRING_SIZE, "QUIT\r\n");
348 r = send_command(f, command); 348 r = send_command(f, command);
349 if (r == -1) { 349 if (r == -1) {
350 res = MAILPOP3_ERROR_STREAM; 350 res = MAILPOP3_ERROR_STREAM;
351 goto close; 351 goto close;
352 } 352 }
353 353
354 response = read_line(f); 354 response = read_line(f);
355 if (response == NULL) { 355 if (response == NULL) {
356 res = MAILPOP3_ERROR_STREAM; 356 res = MAILPOP3_ERROR_STREAM;
357 goto close; 357 goto close;
358 } 358 }
359 parse_response(f, response); 359 parse_response(f, response);
360 360
361 res = MAILPOP3_NO_ERROR; 361 res = MAILPOP3_NO_ERROR;
362 362
363 close: 363 close:
364 mailstream_close(f->pop3_stream); 364 mailstream_close(f->pop3_stream);
365 365
366 if (f->pop3_timestamp != NULL) { 366 if (f->pop3_timestamp != NULL) {
367 free(f->pop3_timestamp); 367 free(f->pop3_timestamp);
368 f->pop3_timestamp = NULL; 368 f->pop3_timestamp = NULL;
369 } 369 }
370 370
371 f->pop3_stream = NULL; 371 f->pop3_stream = NULL;
372 if (f->pop3_msg_tab != NULL) { 372 if (f->pop3_msg_tab != NULL) {
373 mailpop3_msg_info_tab_free(f->pop3_msg_tab); 373 mailpop3_msg_info_tab_free(f->pop3_msg_tab);
374 f->pop3_msg_tab = NULL; 374 f->pop3_msg_tab = NULL;
375 } 375 }
376 376
377 f->pop3_state = POP3_STATE_DISCONNECTED; 377 f->pop3_state = POP3_STATE_DISCONNECTED;
378 378
379 return res; 379 return res;
380} 380}
381 381
382 382
383 383
384 384
385 385
386 386
387 387
388 388
389 389
390 390
391 391
392 392
393 393
394 394
395 395
396 396
397 397
398 398
399 399
400 400
401 401
402 402
403 403
404 404
405 405
406 406
407 407
408 408
409 409
410 410
411 411
412 412
413int mailpop3_apop(mailpop3 * f, 413int mailpop3_apop(mailpop3 * f,
414 const char * user, const char * password) 414 const char * user, const char * password)
415{ 415{
416 char command[POP3_STRING_SIZE]; 416 char command[POP3_STRING_SIZE];
417 MD5_CTX md5context; 417 MD5_CTX md5context;
418 unsigned char md5digest[16]; 418 unsigned char md5digest[16];
419 char md5string[33]; 419 char md5string[33];
420 char * cmd_ptr; 420 char * cmd_ptr;
421 int r; 421 int r;
422 int i; 422 int i;
423 char * response; 423 char * response;
424 424
425 if (f->pop3_state != POP3_STATE_AUTHORIZATION) 425 if (f->pop3_state != POP3_STATE_AUTHORIZATION)
426 return MAILPOP3_ERROR_BAD_STATE; 426 return MAILPOP3_ERROR_BAD_STATE;
427 427
428 if (f->pop3_timestamp == NULL) 428 if (f->pop3_timestamp == NULL)
429 return MAILPOP3_ERROR_APOP_NOT_SUPPORTED; 429 return MAILPOP3_ERROR_APOP_NOT_SUPPORTED;
430 430
431 /* calculate md5 sum */ 431 /* calculate md5 sum */
432 432
433 MD5Init(&md5context); 433 MD5Init(&md5context);
434 MD5Update(&md5context, f->pop3_timestamp, strlen (f->pop3_timestamp)); 434 MD5Update(&md5context, f->pop3_timestamp, strlen (f->pop3_timestamp));
435 MD5Update(&md5context, password, strlen (password)); 435 MD5Update(&md5context, password, strlen (password));
436 MD5Final(md5digest, &md5context); 436 MD5Final(md5digest, &md5context);
437 437
438 cmd_ptr = md5string; 438 cmd_ptr = md5string;
439 for(i = 0 ; i < 16 ; i++, cmd_ptr += 2) 439 for(i = 0 ; i < 16 ; i++, cmd_ptr += 2)
440 snprintf(cmd_ptr, 3, "%02x", md5digest[i]); 440 snprintf(cmd_ptr, 3, "%02x", md5digest[i]);
441 * cmd_ptr = 0; 441 * cmd_ptr = 0;
442 442
443 /* send apop command */ 443 /* send apop command */
444 444
445 snprintf(command, POP3_STRING_SIZE, "APOP %s %s\r\n", user, md5string); 445 snprintf(command, POP3_STRING_SIZE, "APOP %s %s\r\n", user, md5string);
446 r = send_command(f, command); 446 r = send_command(f, command);
447 if (r == -1) 447 if (r == -1)
448 return MAILPOP3_ERROR_STREAM; 448 return MAILPOP3_ERROR_STREAM;
449 449
450 response = read_line(f); 450 response = read_line(f);
451 451
452 if (response == NULL) 452 if (response == NULL)
453 return MAILPOP3_ERROR_STREAM; 453 return MAILPOP3_ERROR_STREAM;
454 r = parse_response(f, response); 454 r = parse_response(f, response);
455 if (r != RESPONSE_OK) 455 if (r != RESPONSE_OK)
456 return MAILPOP3_ERROR_DENIED; 456 return MAILPOP3_ERROR_DENIED;
457 457
458 f->pop3_state = POP3_STATE_TRANSACTION; 458 f->pop3_state = POP3_STATE_TRANSACTION;
459 459
460 return MAILPOP3_NO_ERROR; 460 return MAILPOP3_NO_ERROR;
461} 461}
462 462
463int mailpop3_user(mailpop3 * f, const char * user) 463int mailpop3_user(mailpop3 * f, const char * user)
464{ 464{
465 char command[POP3_STRING_SIZE]; 465 char command[POP3_STRING_SIZE];
466 int r; 466 int r;
467 char * response; 467 char * response;
468 468
469 if (f->pop3_state != POP3_STATE_AUTHORIZATION) 469 if (f->pop3_state != POP3_STATE_AUTHORIZATION)
470 return MAILPOP3_ERROR_BAD_STATE; 470 return MAILPOP3_ERROR_BAD_STATE;
471 471
472 /* send user command */ 472 /* send user command */
473 473
474 snprintf(command, POP3_STRING_SIZE, "USER %s\r\n", user); 474 snprintf(command, POP3_STRING_SIZE, "USER %s\r\n", user);
475 r = send_command(f, command); 475 r = send_command(f, command);
476 if (r == -1) 476 if (r == -1)
477 return MAILPOP3_ERROR_STREAM; 477 return MAILPOP3_ERROR_STREAM;
478 478
479 response = read_line(f); 479 response = read_line(f);
480 if (response == NULL) 480 if (response == NULL)
481 return MAILPOP3_ERROR_STREAM; 481 return MAILPOP3_ERROR_STREAM;
482 r = parse_response(f, response); 482 r = parse_response(f, response);
483 483
484 if (r != RESPONSE_OK) 484 if (r != RESPONSE_OK)
485 return MAILPOP3_ERROR_BAD_USER; 485 return MAILPOP3_ERROR_BAD_USER;
486 486
487 return MAILPOP3_NO_ERROR; 487 return MAILPOP3_NO_ERROR;
488} 488}
489 489
490int mailpop3_pass(mailpop3 * f, const char * password) 490int mailpop3_pass(mailpop3 * f, const char * password)
491{ 491{
492 char command[POP3_STRING_SIZE]; 492 char command[POP3_STRING_SIZE];
493 int r; 493 int r;
494 char * response; 494 char * response;
495 495
496 if (f->pop3_state != POP3_STATE_AUTHORIZATION) 496 if (f->pop3_state != POP3_STATE_AUTHORIZATION)
497 return MAILPOP3_ERROR_BAD_STATE; 497 return MAILPOP3_ERROR_BAD_STATE;
498 498
499 /* send password command */ 499 /* send password command */
500 500
501 snprintf(command, POP3_STRING_SIZE, "PASS %s\r\n", password); 501 snprintf(command, POP3_STRING_SIZE, "PASS %s\r\n", password);
502 r = send_command(f, command); 502 r = send_command(f, command);
503 if (r == -1) 503 if (r == -1)
504 return MAILPOP3_ERROR_STREAM; 504 return MAILPOP3_ERROR_STREAM;
505 505
506 response = read_line(f); 506 response = read_line(f);
507 if (response == NULL) 507 if (response == NULL)
508 return MAILPOP3_ERROR_STREAM; 508 return MAILPOP3_ERROR_STREAM;
509 r = parse_response(f, response); 509 r = parse_response(f, response);
510 510
511 if (r != RESPONSE_OK) 511 if (r != RESPONSE_OK) {
512 // LR
513 fprintf(stderr,"POP3 login error. Response from server:\n%s\n",response );
512 return MAILPOP3_ERROR_BAD_PASSWORD; 514 return MAILPOP3_ERROR_BAD_PASSWORD;
515 }
513 516
514 f->pop3_state = POP3_STATE_TRANSACTION; 517 f->pop3_state = POP3_STATE_TRANSACTION;
515 518
516 return MAILPOP3_NO_ERROR; 519 return MAILPOP3_NO_ERROR;
517} 520}
518 521
519static int read_list(mailpop3 * f, carray ** result); 522static int read_list(mailpop3 * f, carray ** result);
520 523
521 524
522 525
523static int read_uidl(mailpop3 * f, carray * msg_tab); 526static int read_uidl(mailpop3 * f, carray * msg_tab);
524 527
525 528
526 529
527static int mailpop3_do_uidl(mailpop3 * f, carray * msg_tab) 530static int mailpop3_do_uidl(mailpop3 * f, carray * msg_tab)
528{ 531{
529 char command[POP3_STRING_SIZE]; 532 char command[POP3_STRING_SIZE];
530 int r; 533 int r;
531 char * response; 534 char * response;
532 535
533 if (f->pop3_state != POP3_STATE_TRANSACTION) 536 if (f->pop3_state != POP3_STATE_TRANSACTION)
534 return MAILPOP3_ERROR_BAD_STATE; 537 return MAILPOP3_ERROR_BAD_STATE;
535 538
536 /* send list command */ 539 /* send list command */
537 540
538 snprintf(command, POP3_STRING_SIZE, "UIDL\r\n"); 541 snprintf(command, POP3_STRING_SIZE, "UIDL\r\n");
539 r = send_command(f, command); 542 r = send_command(f, command);
540 if (r == -1) 543 if (r == -1)
541 return MAILPOP3_ERROR_STREAM; 544 return MAILPOP3_ERROR_STREAM;
542 545
543 response = read_line(f); 546 response = read_line(f);
544 if (response == NULL) 547 if (response == NULL)
545 return MAILPOP3_ERROR_STREAM; 548 return MAILPOP3_ERROR_STREAM;
546 r = parse_response(f, response); 549 r = parse_response(f, response);
547 550
548 if (r != RESPONSE_OK) 551 if (r != RESPONSE_OK)
549 return MAILPOP3_ERROR_CANT_LIST; 552 return MAILPOP3_ERROR_CANT_LIST;
550 553
551 r = read_uidl(f, msg_tab); 554 r = read_uidl(f, msg_tab);
552 if (r != MAILPOP3_NO_ERROR) 555 if (r != MAILPOP3_NO_ERROR)
553 return r; 556 return r;
554 557
555 return MAILPOP3_NO_ERROR; 558 return MAILPOP3_NO_ERROR;
556} 559}
557 560
558 561
559 562
560static int mailpop3_do_list(mailpop3 * f) 563static int mailpop3_do_list(mailpop3 * f)
561{ 564{
562 char command[POP3_STRING_SIZE]; 565 char command[POP3_STRING_SIZE];
563 int r; 566 int r;
564 carray * msg_tab; 567 carray * msg_tab;
565 char * response; 568 char * response;
566 569
567 if (f->pop3_msg_tab != NULL) { 570 if (f->pop3_msg_tab != NULL) {
568 mailpop3_msg_info_tab_free(f->pop3_msg_tab); 571 mailpop3_msg_info_tab_free(f->pop3_msg_tab);
569 f->pop3_msg_tab = NULL; 572 f->pop3_msg_tab = NULL;
570 } 573 }
571 574
572 if (f->pop3_state != POP3_STATE_TRANSACTION) 575 if (f->pop3_state != POP3_STATE_TRANSACTION)
573 return MAILPOP3_ERROR_BAD_STATE; 576 return MAILPOP3_ERROR_BAD_STATE;
574 577
575 /* send list command */ 578 /* send list command */
576 579
577 snprintf(command, POP3_STRING_SIZE, "LIST\r\n"); 580 snprintf(command, POP3_STRING_SIZE, "LIST\r\n");
578 r = send_command(f, command); 581 r = send_command(f, command);
579 if (r == -1) 582 if (r == -1)
580 return MAILPOP3_ERROR_STREAM; 583 return MAILPOP3_ERROR_STREAM;
581 584
582 response = read_line(f); 585 response = read_line(f);
583 if (response == NULL) 586 if (response == NULL)
584 return MAILPOP3_ERROR_STREAM; 587 return MAILPOP3_ERROR_STREAM;
585 r = parse_response(f, response); 588 r = parse_response(f, response);
586 589
587 if (r != RESPONSE_OK) 590 if (r != RESPONSE_OK)
588 return MAILPOP3_ERROR_CANT_LIST; 591 return MAILPOP3_ERROR_CANT_LIST;
589 592
590 r = read_list(f, &msg_tab); 593 r = read_list(f, &msg_tab);
591 if (r != MAILPOP3_NO_ERROR) 594 if (r != MAILPOP3_NO_ERROR)
592 return r; 595 return r;
593 596
594 f->pop3_msg_tab = msg_tab; 597 f->pop3_msg_tab = msg_tab;
595 f->pop3_deleted_count = 0; 598 f->pop3_deleted_count = 0;
596 599
597 mailpop3_do_uidl(f, msg_tab); 600 mailpop3_do_uidl(f, msg_tab);
598 601
599 return MAILPOP3_NO_ERROR; 602 return MAILPOP3_NO_ERROR;
600} 603}
601 604
602 605
603 606
604static void mailpop3_list_if_needed(mailpop3 * f) 607static void mailpop3_list_if_needed(mailpop3 * f)
605{ 608{
606 if (f->pop3_msg_tab == NULL) 609 if (f->pop3_msg_tab == NULL)
607 mailpop3_do_list(f); 610 mailpop3_do_list(f);
608} 611}
609 612
610/* 613/*
611 mailpop3_list 614 mailpop3_list
612*/ 615*/
613 616
614void mailpop3_list(mailpop3 * f, carray ** result) 617void mailpop3_list(mailpop3 * f, carray ** result)
615{ 618{
616 mailpop3_list_if_needed(f); 619 mailpop3_list_if_needed(f);
617 * result = f->pop3_msg_tab; 620 * result = f->pop3_msg_tab;
618} 621}
619 622
620static inline struct mailpop3_msg_info * 623static inline struct mailpop3_msg_info *
621find_msg(mailpop3 * f, unsigned int index) 624find_msg(mailpop3 * f, unsigned int index)
622{ 625{
623 mailpop3_list_if_needed(f); 626 mailpop3_list_if_needed(f);
624 627
625 if (f->pop3_msg_tab == NULL) 628 if (f->pop3_msg_tab == NULL)
626 return NULL; 629 return NULL;
627 630
628 return mailpop3_msg_info_tab_find_msg(f->pop3_msg_tab, index); 631 return mailpop3_msg_info_tab_find_msg(f->pop3_msg_tab, index);
629} 632}
630 633
631 634
632 635
633 636
634 637
635 638
636 639
637 640
638static void mailpop3_multiline_response_free(char * str) 641static void mailpop3_multiline_response_free(char * str)
639{ 642{
640 mmap_string_unref(str); 643 mmap_string_unref(str);
641} 644}
642 645
643void mailpop3_top_free(char * str) 646void mailpop3_top_free(char * str)
644{ 647{
645 mailpop3_multiline_response_free(str); 648 mailpop3_multiline_response_free(str);
646} 649}
647 650
648void mailpop3_retr_free(char * str) 651void mailpop3_retr_free(char * str)
649{ 652{
650 mailpop3_multiline_response_free(str); 653 mailpop3_multiline_response_free(str);
651} 654}
652 655
653/* 656/*
654 mailpop3_retr 657 mailpop3_retr
655 658
656 message content in (* result) is still there until the 659 message content in (* result) is still there until the
657 next retrieve or top operation on the mailpop3 structure 660 next retrieve or top operation on the mailpop3 structure
658*/ 661*/
659 662
660static int 663static int
661mailpop3_get_content(mailpop3 * f, struct mailpop3_msg_info * msginfo, 664mailpop3_get_content(mailpop3 * f, struct mailpop3_msg_info * msginfo,
662 char ** result, size_t * result_len) 665 char ** result, size_t * result_len)
663{ 666{
664 char * response; 667 char * response;
665 char * result_multiline; 668 char * result_multiline;
666 MMAPString * buffer; 669 MMAPString * buffer;
667 int r; 670 int r;
668 671
669 response = read_line(f); 672 response = read_line(f);
670 if (response == NULL) 673 if (response == NULL)
671 return MAILPOP3_ERROR_STREAM; 674 return MAILPOP3_ERROR_STREAM;
672 r = parse_response(f, response); 675 r = parse_response(f, response);
673 if (r != RESPONSE_OK) 676 if (r != RESPONSE_OK)
674 return MAILPOP3_ERROR_NO_SUCH_MESSAGE; 677 return MAILPOP3_ERROR_NO_SUCH_MESSAGE;
675 678
676 buffer = mmap_string_new(""); 679 buffer = mmap_string_new("");
677 if (buffer == NULL) 680 if (buffer == NULL)
678 return MAILPOP3_ERROR_MEMORY; 681 return MAILPOP3_ERROR_MEMORY;
679 682
680 result_multiline = read_multiline(f, msginfo->msg_size, buffer); 683 result_multiline = read_multiline(f, msginfo->msg_size, buffer);
681 if (result_multiline == NULL) { 684 if (result_multiline == NULL) {
682 mmap_string_free(buffer); 685 mmap_string_free(buffer);
683 return MAILPOP3_ERROR_STREAM; 686 return MAILPOP3_ERROR_STREAM;
684 } 687 }
685 else { 688 else {
686 r = mmap_string_ref(buffer); 689 r = mmap_string_ref(buffer);
687 if (r < 0) { 690 if (r < 0) {
688 mmap_string_free(buffer); 691 mmap_string_free(buffer);
689 return MAILPOP3_ERROR_MEMORY; 692 return MAILPOP3_ERROR_MEMORY;
690 } 693 }
691 694
692 * result = result_multiline; 695 * result = result_multiline;
693 * result_len = buffer->len; 696 * result_len = buffer->len;
694 return MAILPOP3_NO_ERROR; 697 return MAILPOP3_NO_ERROR;
695 } 698 }
696} 699}
697 700
698int mailpop3_retr(mailpop3 * f, unsigned int index, char ** result, 701int mailpop3_retr(mailpop3 * f, unsigned int index, char ** result,
699 size_t * result_len) 702 size_t * result_len)
700{ 703{
701 char command[POP3_STRING_SIZE]; 704 char command[POP3_STRING_SIZE];
702 struct mailpop3_msg_info * msginfo; 705 struct mailpop3_msg_info * msginfo;
703 int r; 706 int r;
704 707
705 if (f->pop3_state != POP3_STATE_TRANSACTION) 708 if (f->pop3_state != POP3_STATE_TRANSACTION)
706 return MAILPOP3_ERROR_BAD_STATE; 709 return MAILPOP3_ERROR_BAD_STATE;
707 710
708 msginfo = find_msg(f, index); 711 msginfo = find_msg(f, index);
709 712
710 if (msginfo == NULL) { 713 if (msginfo == NULL) {
711 f->pop3_response = NULL; 714 f->pop3_response = NULL;
712 return MAILPOP3_ERROR_NO_SUCH_MESSAGE; 715 return MAILPOP3_ERROR_NO_SUCH_MESSAGE;
713 } 716 }
714 717
715 snprintf(command, POP3_STRING_SIZE, "RETR %i\r\n", index); 718 snprintf(command, POP3_STRING_SIZE, "RETR %i\r\n", index);
716 r = send_command(f, command); 719 r = send_command(f, command);
717 if (r == -1) 720 if (r == -1)
718 return MAILPOP3_ERROR_STREAM; 721 return MAILPOP3_ERROR_STREAM;
719 722
720 return mailpop3_get_content(f, msginfo, result, result_len); 723 return mailpop3_get_content(f, msginfo, result, result_len);
721} 724}
722 725
723int mailpop3_top(mailpop3 * f, unsigned int index, 726int mailpop3_top(mailpop3 * f, unsigned int index,
724 uint32_t count, char ** result, 727 uint32_t count, char ** result,
725 size_t * result_len) 728 size_t * result_len)
726{ 729{
727 char command[POP3_STRING_SIZE]; 730 char command[POP3_STRING_SIZE];
728 struct mailpop3_msg_info * msginfo; 731 struct mailpop3_msg_info * msginfo;
729 int r; 732 int r;
730 733
731 if (f->pop3_state != POP3_STATE_TRANSACTION) 734 if (f->pop3_state != POP3_STATE_TRANSACTION)
732 return MAILPOP3_ERROR_BAD_STATE; 735 return MAILPOP3_ERROR_BAD_STATE;
733 736
734 msginfo = find_msg(f, index); 737 msginfo = find_msg(f, index);
735 738
736 if (msginfo == NULL) { 739 if (msginfo == NULL) {
737 f->pop3_response = NULL; 740 f->pop3_response = NULL;
738 return MAILPOP3_ERROR_NO_SUCH_MESSAGE; 741 return MAILPOP3_ERROR_NO_SUCH_MESSAGE;
739 } 742 }
740 743
741 snprintf(command, POP3_STRING_SIZE, "TOP %i %i\r\n", index, count); 744 snprintf(command, POP3_STRING_SIZE, "TOP %i %i\r\n", index, count);
742 r = send_command(f, command); 745 r = send_command(f, command);
743 if (r == -1) 746 if (r == -1)
744 return MAILPOP3_ERROR_STREAM; 747 return MAILPOP3_ERROR_STREAM;
745 748
746 return mailpop3_get_content(f, msginfo, result, result_len); 749 return mailpop3_get_content(f, msginfo, result, result_len);
747} 750}
748 751
749int mailpop3_dele(mailpop3 * f, unsigned int index) 752int mailpop3_dele(mailpop3 * f, unsigned int index)
750{ 753{
751 char command[POP3_STRING_SIZE]; 754 char command[POP3_STRING_SIZE];
752 struct mailpop3_msg_info * msginfo; 755 struct mailpop3_msg_info * msginfo;
753 char * response; 756 char * response;
754 int r; 757 int r;
755 758
756 if (f->pop3_state != POP3_STATE_TRANSACTION) 759 if (f->pop3_state != POP3_STATE_TRANSACTION)
757 return MAILPOP3_ERROR_BAD_STATE; 760 return MAILPOP3_ERROR_BAD_STATE;
758 761
759 msginfo = find_msg(f, index); 762 msginfo = find_msg(f, index);
760 763
761 if (msginfo == NULL) { 764 if (msginfo == NULL) {
762 f->pop3_response = NULL; 765 f->pop3_response = NULL;
763 return MAILPOP3_ERROR_NO_SUCH_MESSAGE; 766 return MAILPOP3_ERROR_NO_SUCH_MESSAGE;
764 } 767 }
765 768
766 snprintf(command, POP3_STRING_SIZE, "DELE %i\r\n", index); 769 snprintf(command, POP3_STRING_SIZE, "DELE %i\r\n", index);
767 r = send_command(f, command); 770 r = send_command(f, command);
768 if (r == -1) 771 if (r == -1)
769 return MAILPOP3_ERROR_STREAM; 772 return MAILPOP3_ERROR_STREAM;
770 773
771 response = read_line(f); 774 response = read_line(f);
772 if (response == NULL) 775 if (response == NULL)
773 return MAILPOP3_ERROR_STREAM; 776 return MAILPOP3_ERROR_STREAM;
774 r = parse_response(f, response); 777 r = parse_response(f, response);
775 if (r != RESPONSE_OK) 778 if (r != RESPONSE_OK)
776 return MAILPOP3_ERROR_NO_SUCH_MESSAGE; 779 return MAILPOP3_ERROR_NO_SUCH_MESSAGE;
777 780
778 msginfo->msg_deleted = TRUE; 781 msginfo->msg_deleted = TRUE;
779 f->pop3_deleted_count ++; 782 f->pop3_deleted_count ++;
780 783
781 return MAILPOP3_NO_ERROR; 784 return MAILPOP3_NO_ERROR;
782} 785}
783 786
784int mailpop3_noop(mailpop3 * f) 787int mailpop3_noop(mailpop3 * f)
785{ 788{
786 char command[POP3_STRING_SIZE]; 789 char command[POP3_STRING_SIZE];
787 char * response; 790 char * response;
788 int r; 791 int r;
789 792
790 if (f->pop3_state != POP3_STATE_TRANSACTION) 793 if (f->pop3_state != POP3_STATE_TRANSACTION)
791 return MAILPOP3_ERROR_BAD_STATE; 794 return MAILPOP3_ERROR_BAD_STATE;
792 795
793 snprintf(command, POP3_STRING_SIZE, "NOOP\r\n"); 796 snprintf(command, POP3_STRING_SIZE, "NOOP\r\n");
794 r = send_command(f, command); 797 r = send_command(f, command);
795 if (r == -1) 798 if (r == -1)
796 return MAILPOP3_ERROR_STREAM; 799 return MAILPOP3_ERROR_STREAM;
797 800
798 response = read_line(f); 801 response = read_line(f);
799 if (response == NULL) 802 if (response == NULL)
800 return MAILPOP3_ERROR_STREAM; 803 return MAILPOP3_ERROR_STREAM;
801 parse_response(f, response); 804 parse_response(f, response);
802 805
803 return MAILPOP3_NO_ERROR; 806 return MAILPOP3_NO_ERROR;
804} 807}
805 808
806int mailpop3_rset(mailpop3 * f) 809int mailpop3_rset(mailpop3 * f)
807{ 810{
808 char command[POP3_STRING_SIZE]; 811 char command[POP3_STRING_SIZE];
809 char * response; 812 char * response;
810 int r; 813 int r;
811 814
812 if (f->pop3_state != POP3_STATE_TRANSACTION) 815 if (f->pop3_state != POP3_STATE_TRANSACTION)
813 return MAILPOP3_ERROR_BAD_STATE; 816 return MAILPOP3_ERROR_BAD_STATE;
814 817
815 snprintf(command, POP3_STRING_SIZE, "RSET\r\n"); 818 snprintf(command, POP3_STRING_SIZE, "RSET\r\n");
816 r = send_command(f, command); 819 r = send_command(f, command);
817 if (r == -1) 820 if (r == -1)
818 return MAILPOP3_ERROR_STREAM; 821 return MAILPOP3_ERROR_STREAM;
819 822
820 response = read_line(f); 823 response = read_line(f);
821 if (response == NULL) 824 if (response == NULL)
822 return MAILPOP3_ERROR_STREAM; 825 return MAILPOP3_ERROR_STREAM;
823 parse_response(f, response); 826 parse_response(f, response);
824 827
825 if (f->pop3_msg_tab != NULL) { 828 if (f->pop3_msg_tab != NULL) {
826 mailpop3_msg_info_tab_reset(f->pop3_msg_tab); 829 mailpop3_msg_info_tab_reset(f->pop3_msg_tab);
827 f->pop3_deleted_count = 0; 830 f->pop3_deleted_count = 0;
828 } 831 }
829 832
830 return MAILPOP3_NO_ERROR; 833 return MAILPOP3_NO_ERROR;
831} 834}
832 835
833 836
834 837
835static int read_capa_resp(mailpop3 * f, clist ** result); 838static int read_capa_resp(mailpop3 * f, clist ** result);
836 839
837int mailpop3_capa(mailpop3 * f, clist ** result) 840int mailpop3_capa(mailpop3 * f, clist ** result)
838{ 841{
839 clist * capa_list; 842 clist * capa_list;
840 char command[POP3_STRING_SIZE]; 843 char command[POP3_STRING_SIZE];
841 int r; 844 int r;
842 char * response; 845 char * response;
843 846
844 snprintf(command, POP3_STRING_SIZE, "CAPA\r\n"); 847 snprintf(command, POP3_STRING_SIZE, "CAPA\r\n");
845 r = send_command(f, command); 848 r = send_command(f, command);
846 if (r == -1) 849 if (r == -1)
847 return MAILPOP3_ERROR_STREAM; 850 return MAILPOP3_ERROR_STREAM;
848 851
849 response = read_line(f); 852 response = read_line(f);
850 if (response == NULL) 853 if (response == NULL)
851 return MAILPOP3_ERROR_STREAM; 854 return MAILPOP3_ERROR_STREAM;
852 r = parse_response(f, response); 855 r = parse_response(f, response);
853 856
854 if (r != RESPONSE_OK) 857 if (r != RESPONSE_OK)
855 return MAILPOP3_ERROR_CAPA_NOT_SUPPORTED; 858 return MAILPOP3_ERROR_CAPA_NOT_SUPPORTED;
856 859
857 r = read_capa_resp(f, &capa_list); 860 r = read_capa_resp(f, &capa_list);
858 if (r != MAILPOP3_NO_ERROR) 861 if (r != MAILPOP3_NO_ERROR)
859 return r; 862 return r;
860 863
861 * result = capa_list; 864 * result = capa_list;
862 865
863 return MAILPOP3_NO_ERROR; 866 return MAILPOP3_NO_ERROR;
864} 867}
865 868
866void mailpop3_capa_resp_free(clist * capa_list) 869void mailpop3_capa_resp_free(clist * capa_list)
867{ 870{
868 clist_foreach(capa_list, (clist_func) mailpop3_capa_free, NULL); 871 clist_foreach(capa_list, (clist_func) mailpop3_capa_free, NULL);
869 clist_free(capa_list); 872 clist_free(capa_list);
870} 873}
871 874
872int mailpop3_stls(mailpop3 * f) 875int mailpop3_stls(mailpop3 * f)
873{ 876{
874 char command[POP3_STRING_SIZE]; 877 char command[POP3_STRING_SIZE];
875 int r; 878 int r;
876 char * response; 879 char * response;
877 880
878 snprintf(command, POP3_STRING_SIZE, "STLS\r\n"); 881 snprintf(command, POP3_STRING_SIZE, "STLS\r\n");
879 r = send_command(f, command); 882 r = send_command(f, command);
880 if (r == -1) 883 if (r == -1)
881 return MAILPOP3_ERROR_STREAM; 884 return MAILPOP3_ERROR_STREAM;
882 885
883 response = read_line(f); 886 response = read_line(f);
884 if (response == NULL) 887 if (response == NULL)
885 return MAILPOP3_ERROR_STREAM; 888 return MAILPOP3_ERROR_STREAM;
886 r = parse_response(f, response); 889 r = parse_response(f, response);
887 890
888 if (r != RESPONSE_OK) 891 if (r != RESPONSE_OK)
889 return MAILPOP3_ERROR_STLS_NOT_SUPPORTED; 892 return MAILPOP3_ERROR_STLS_NOT_SUPPORTED;
890 893
891 return MAILPOP3_NO_ERROR; 894 return MAILPOP3_NO_ERROR;
892} 895}
893 896
894 897
895 898
896 899
897 900
898 901
899 902
900 903
901 904
902 905
903 906
904 907
905 908
906 909
907 910
908 911
909 912
910 913
911 914
912 915
913 916
914 917
915 918
916 919
917#define RESP_OK_STR "+OK" 920#define RESP_OK_STR "+OK"
918#define RESP_ERR_STR "-ERR" 921#define RESP_ERR_STR "-ERR"
919 922
920 923
921static int parse_space(char ** line) 924static int parse_space(char ** line)
922{ 925{
923 char * p; 926 char * p;
924 927
925 p = * line; 928 p = * line;
926 929
927 while ((* p == ' ') || (* p == '\t')) 930 while ((* p == ' ') || (* p == '\t'))
928 p ++; 931 p ++;
929 932
930 if (p != * line) { 933 if (p != * line) {
931 * line = p; 934 * line = p;
932 return TRUE; 935 return TRUE;
933 } 936 }
934 else 937 else
935 return FALSE; 938 return FALSE;
936} 939}
937 940
938static char * cut_token(char * line) 941static char * cut_token(char * line)
939{ 942{
940 char * p; 943 char * p;
941 char * p_tab; 944 char * p_tab;
942 char * p_space; 945 char * p_space;
943 946
944 p = line; 947 p = line;
945 948
946 p_space = strchr(line, ' '); 949 p_space = strchr(line, ' ');
947 p_tab = strchr(line, '\t'); 950 p_tab = strchr(line, '\t');
948 if (p_tab == NULL) 951 if (p_tab == NULL)
949 p = p_space; 952 p = p_space;
950 else if (p_space == NULL) 953 else if (p_space == NULL)
951 p = p_tab; 954 p = p_tab;
952 else { 955 else {
953 if (p_tab < p_space) 956 if (p_tab < p_space)
954 p = p_tab; 957 p = p_tab;
955 else 958 else
956 p = p_space; 959 p = p_space;
957 } 960 }
958 if (p == NULL) 961 if (p == NULL)
959 return NULL; 962 return NULL;
960 * p = 0; 963 * p = 0;
961 p ++; 964 p ++;
962 965
963 return p; 966 return p;
964} 967}
965 968
966 969
967static int parse_response(mailpop3 * f, char * response) 970static int parse_response(mailpop3 * f, char * response)
968{ 971{
969 char * msg; 972 char * msg;
970 973
971 if (response == NULL) { 974 if (response == NULL) {
972 f->pop3_response = NULL; 975 f->pop3_response = NULL;
973 return RESPONSE_ERR; 976 return RESPONSE_ERR;
974 } 977 }
975 978
976 if (strncmp(response, RESP_OK_STR, strlen(RESP_OK_STR)) == 0) { 979 if (strncmp(response, RESP_OK_STR, strlen(RESP_OK_STR)) == 0) {
977 980
978 if (response[strlen(RESP_OK_STR)] == ' ') 981 if (response[strlen(RESP_OK_STR)] == ' ')
979 msg = response + strlen(RESP_OK_STR) + 1; 982 msg = response + strlen(RESP_OK_STR) + 1;
980 else 983 else
981 msg = response + strlen(RESP_OK_STR); 984 msg = response + strlen(RESP_OK_STR);
982 985
983 if (mmap_string_assign(f->pop3_response_buffer, msg)) 986 if (mmap_string_assign(f->pop3_response_buffer, msg))
984 f->pop3_response = f->pop3_response_buffer->str; 987 f->pop3_response = f->pop3_response_buffer->str;
985 else 988 else
986 f->pop3_response = NULL; 989 f->pop3_response = NULL;
987 990
988 return RESPONSE_OK; 991 return RESPONSE_OK;
989 } 992 }
990 else if (strncmp(response, RESP_ERR_STR, strlen(RESP_ERR_STR)) == 0) { 993 else if (strncmp(response, RESP_ERR_STR, strlen(RESP_ERR_STR)) == 0) {
991 994
992 if (response[strlen(RESP_ERR_STR)] == ' ') 995 if (response[strlen(RESP_ERR_STR)] == ' ')
993 msg = response + strlen(RESP_ERR_STR) + 1; 996 msg = response + strlen(RESP_ERR_STR) + 1;
994 else 997 else
995 msg = response + strlen(RESP_ERR_STR); 998 msg = response + strlen(RESP_ERR_STR);
996 999
997 if (mmap_string_assign(f->pop3_response_buffer, msg)) 1000 if (mmap_string_assign(f->pop3_response_buffer, msg))
998 f->pop3_response = f->pop3_response_buffer->str; 1001 f->pop3_response = f->pop3_response_buffer->str;
999 else 1002 else
1000 f->pop3_response = NULL; 1003 f->pop3_response = NULL;
1001 } 1004 }
1002 1005
1003 f->pop3_response = NULL; 1006 f->pop3_response = NULL;
1004 return RESPONSE_ERR; 1007 return RESPONSE_ERR;
1005} 1008}
1006 1009
1007 1010
1008 1011
1009 1012
1010 1013
1011 1014
1012 1015
1013static int read_list(mailpop3 * f, carray ** result) 1016static int read_list(mailpop3 * f, carray ** result)
1014{ 1017{
1015 unsigned int index; 1018 unsigned int index;
1016 uint32_t size; 1019 uint32_t size;
1017 carray * msg_tab; 1020 carray * msg_tab;
1018 struct mailpop3_msg_info * msg; 1021 struct mailpop3_msg_info * msg;
1019 char * line; 1022 char * line;
1020 1023
1021 msg_tab = carray_new(128); 1024 msg_tab = carray_new(128);
1022 if (msg_tab == NULL) 1025 if (msg_tab == NULL)
1023 goto err; 1026 goto err;
1024 1027
diff --git a/kmicromail/libetpan/tools/mailstream_helper.c b/kmicromail/libetpan/tools/mailstream_helper.c
index 146f955..92f4ffe 100644
--- a/kmicromail/libetpan/tools/mailstream_helper.c
+++ b/kmicromail/libetpan/tools/mailstream_helper.c
@@ -1,383 +1,390 @@
1/* 1/*
2 * libEtPan! -- a mail stuff library 2 * libEtPan! -- a mail stuff library
3 * 3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa 4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its 15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived 16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission. 17 * from this software without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * $Id$ 33 * $Id$
34 */ 34 */
35 35
36#include "mailstream_helper.h" 36#include "mailstream_helper.h"
37#include <string.h> 37#include <string.h>
38#include <stdio.h> 38#include <stdio.h>
39#include "mail.h" 39#include "mail.h"
40 40
41static void remove_trailing_eol(MMAPString * mmapstr) 41static void remove_trailing_eol(MMAPString * mmapstr)
42{ 42{
43 if (mmapstr->str[mmapstr->len - 1] == '\n') { 43 if (mmapstr->str[mmapstr->len - 1] == '\n') {
44 mmapstr->len --; 44 mmapstr->len --;
45 mmapstr->str[mmapstr->len] = '\0'; 45 mmapstr->str[mmapstr->len] = '\0';
46 } 46 }
47 if (mmapstr->str[mmapstr->len - 1] == '\r') { 47 if (mmapstr->str[mmapstr->len - 1] == '\r') {
48 mmapstr->len --; 48 mmapstr->len --;
49 mmapstr->str[mmapstr->len] = '\0'; 49 mmapstr->str[mmapstr->len] = '\0';
50 } 50 }
51} 51}
52 52
53char * mailstream_read_line(mailstream * stream, MMAPString * line) 53char * mailstream_read_line(mailstream * stream, MMAPString * line)
54{ 54{
55 if (mmap_string_assign(line, "") == NULL) 55 if (mmap_string_assign(line, "") == NULL)
56 return NULL; 56 return NULL;
57 57
58 return mailstream_read_line_append(stream, line); 58 return mailstream_read_line_append(stream, line);
59} 59}
60 60
61static char * mailstream_read_len_append(mailstream * stream, 61static char * mailstream_read_len_append(mailstream * stream,
62 MMAPString * line, 62 MMAPString * line,
63 size_t i) 63 size_t i)
64{ 64{
65 size_t cur_size; 65 size_t cur_size;
66 66
67 cur_size = line->len; 67 cur_size = line->len;
68 if (mmap_string_set_size(line, line->len + i) == NULL) 68 if (mmap_string_set_size(line, line->len + i) == NULL)
69 return NULL; 69 return NULL;
70 if (mailstream_read(stream, line->str + cur_size, i) < 0) 70 if (mailstream_read(stream, line->str + cur_size, i) < 0)
71 return NULL; 71 return NULL;
72 return line->str; 72 return line->str;
73} 73}
74 74
75char * mailstream_read_line_append(mailstream * stream, MMAPString * line) 75char * mailstream_read_line_append(mailstream * stream, MMAPString * line)
76{ 76{
77 if (stream == NULL) 77 if (stream == NULL)
78 return NULL; 78 return NULL;
79 79
80 do { 80 do {
81 if (stream->read_buffer_len > 0) { 81 if (stream->read_buffer_len > 0) {
82 size_t i; 82 size_t i;
83 83
84 i = 0; 84 i = 0;
85 while (i < stream->read_buffer_len) { 85 while (i < stream->read_buffer_len) {
86 if (stream->read_buffer[i] == '\n') 86 if (stream->read_buffer[i] == '\n')
87 return mailstream_read_len_append(stream, line, i + 1); 87 return mailstream_read_len_append(stream, line, i + 1);
88 i++; 88 i++;
89 } 89 }
90 if (mailstream_read_len_append(stream, line, 90 if (mailstream_read_len_append(stream, line,
91 stream->read_buffer_len) == NULL) 91 stream->read_buffer_len) == NULL)
92 return NULL; 92 return NULL;
93 } 93 }
94 else { 94 else {
95 ssize_t r; 95 ssize_t r;
96 96
97 r = mailstream_feed_read_buffer(stream); 97 r = mailstream_feed_read_buffer(stream);
98 if (r == -1) 98 if (r == -1)
99 return NULL; 99 return NULL;
100 100
101 if (r == 0) 101 if (r == 0) {
102 break; 102 // LR
103 // this avoids a memory access violation later when trying
104 // to remove_trailing_eol from a null string
105 if ( line->len == 0 )
106 return NULL;
107 else
108 break;
109 }
103 } 110 }
104 } 111 }
105 while (1); 112 while (1);
106 113
107 return line->str; 114 return line->str;
108} 115}
109 116
110char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line) 117char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line)
111{ 118{
112 if (!mailstream_read_line(stream, line)) 119 if (!mailstream_read_line(stream, line))
113 return NULL; 120 return NULL;
114 121
115 remove_trailing_eol(line); 122 remove_trailing_eol(line);
116 123
117 return line->str; 124 return line->str;
118} 125}
119 126
120int mailstream_is_end_multiline(const char * line) 127int mailstream_is_end_multiline(const char * line)
121{ 128{
122 if (line[0] != '.') 129 if (line[0] != '.')
123 return FALSE; 130 return FALSE;
124 if (line[1] != 0) 131 if (line[1] != 0)
125 return FALSE; 132 return FALSE;
126 return TRUE; 133 return TRUE;
127} 134}
128 135
129#if 1 136#if 1
130char * mailstream_read_multiline(mailstream * s, size_t size, 137char * mailstream_read_multiline(mailstream * s, size_t size,
131 MMAPString * stream_buffer, 138 MMAPString * stream_buffer,
132 MMAPString * multiline_buffer, 139 MMAPString * multiline_buffer,
133 size_t progr_rate, 140 size_t progr_rate,
134 progress_function * progr_fun) 141 progress_function * progr_fun)
135{ 142{
136 size_t count; 143 size_t count;
137 char * line; 144 char * line;
138 size_t last; 145 size_t last;
139 146
140 if (mmap_string_assign(multiline_buffer, "") == NULL) 147 if (mmap_string_assign(multiline_buffer, "") == NULL)
141 return NULL; 148 return NULL;
142 149
143 count = 0; 150 count = 0;
144 last = 0; 151 last = 0;
145 152
146 while ((line = mailstream_read_line_remove_eol(s, stream_buffer)) != NULL) { 153 while ((line = mailstream_read_line_remove_eol(s, stream_buffer)) != NULL) {
147 if (mailstream_is_end_multiline(line)) 154 if (mailstream_is_end_multiline(line))
148 return multiline_buffer->str; 155 return multiline_buffer->str;
149 156
150 if (line[0] == '.') { 157 if (line[0] == '.') {
151 if (mmap_string_append(multiline_buffer, line + 1) == NULL) 158 if (mmap_string_append(multiline_buffer, line + 1) == NULL)
152 return NULL; 159 return NULL;
153 } 160 }
154 else { 161 else {
155 if (mmap_string_append(multiline_buffer, line) == NULL) 162 if (mmap_string_append(multiline_buffer, line) == NULL)
156 return NULL; 163 return NULL;
157 } 164 }
158 if (mmap_string_append(multiline_buffer, "\r\n") == NULL) 165 if (mmap_string_append(multiline_buffer, "\r\n") == NULL)
159 return NULL; 166 return NULL;
160 167
161 count += strlen(line); 168 count += strlen(line);
162 if ((size != 0) && (progr_rate != 0) && (progr_fun != NULL)) 169 if ((size != 0) && (progr_rate != 0) && (progr_fun != NULL))
163 if (count - last >= progr_rate) { 170 if (count - last >= progr_rate) {
164 (* progr_fun)(count, size); 171 (* progr_fun)(count, size);
165 last = count; 172 last = count;
166 } 173 }
167 } 174 }
168 175
169 return NULL; 176 return NULL;
170} 177}
171 178
172#else 179#else
173 180
174/* 181/*
175 high speed but don't replace the line break with '\n' and neither 182 high speed but don't replace the line break with '\n' and neither
176 remove the '.' 183 remove the '.'
177*/ 184*/
178 185
179static gboolean end_of_multiline(const char * str, gint len) 186static gboolean end_of_multiline(const char * str, gint len)
180{ 187{
181 gint index; 188 gint index;
182 189
183 index = len - 1; 190 index = len - 1;
184 191
185 if (str[index] != '\n') 192 if (str[index] != '\n')
186 return FALSE; 193 return FALSE;
187 if (index == 0) 194 if (index == 0)
188 return FALSE; 195 return FALSE;
189 196
190 index --; 197 index --;
191 198
192 if (str[index] == '\r') { 199 if (str[index] == '\r') {
193 index --; 200 index --;
194 if (index == 0) 201 if (index == 0)
195 return FALSE; 202 return FALSE;
196 } 203 }
197 204
198 if (str[index] != '.') 205 if (str[index] != '.')
199 return FALSE; 206 return FALSE;
200 if (index == 0) 207 if (index == 0)
201 return FALSE; 208 return FALSE;
202 209
203 index--; 210 index--;
204 211
205 if (str[index] != '\n') 212 if (str[index] != '\n')
206 return FALSE; 213 return FALSE;
207 214
208 return TRUE; 215 return TRUE;
209} 216}
210 217
211char * mailstream_read_multiline(mailstream * stream, size_t size, 218char * mailstream_read_multiline(mailstream * stream, size_t size,
212 MMAPString * stream_buffer, 219 MMAPString * stream_buffer,
213 MMAPString * line, 220 MMAPString * line,
214 size_t progr_rate, 221 size_t progr_rate,
215 progress_function * progr_fun) 222 progress_function * progr_fun)
216{ 223{
217 if (stream == NULL) 224 if (stream == NULL)
218 return NULL; 225 return NULL;
219 226
220 mmap_string_assign(line, ""); 227 mmap_string_assign(line, "");
221 228
222 do { 229 do {
223 if (stream->read_buffer_len > 0) { 230 if (stream->read_buffer_len > 0) {
224 size_t i; 231 size_t i;
225 232
226 i = 0; 233 i = 0;
227 while (i < stream->read_buffer_len) { 234 while (i < stream->read_buffer_len) {
228 if (end_of_multiline(stream->read_buffer, i + 1)) 235 if (end_of_multiline(stream->read_buffer, i + 1))
229 return mailstream_read_len_append(stream, line, i + 1); 236 return mailstream_read_len_append(stream, line, i + 1);
230 i++; 237 i++;
231 } 238 }
232 if (mailstream_read_len_append(stream, line, 239 if (mailstream_read_len_append(stream, line,
233 stream->read_buffer_len) == NULL) 240 stream->read_buffer_len) == NULL)
234 return NULL; 241 return NULL;
235 if (end_of_multiline(line->str, line->len)) 242 if (end_of_multiline(line->str, line->len))
236 return line->str; 243 return line->str;
237 } 244 }
238 else 245 else
239 if (mailstream_feed_read_buffer(stream) == -1) 246 if (mailstream_feed_read_buffer(stream) == -1)
240 return NULL; 247 return NULL;
241 } 248 }
242 while (1); 249 while (1);
243 250
244 return line->str; 251 return line->str;
245} 252}
246#endif 253#endif
247 254
248 255
249 256
250static ssize_t send_data_line(mailstream * s, const char * line, size_t length) 257static ssize_t send_data_line(mailstream * s, const char * line, size_t length)
251{ 258{
252 int fix_eol; 259 int fix_eol;
253 const char * start; 260 const char * start;
254 size_t count; 261 size_t count;
255 262
256 start = line; 263 start = line;
257 264
258 fix_eol = 0; 265 fix_eol = 0;
259 count = 0; 266 count = 0;
260 267
261 while (1) { 268 while (1) {
262 if (length == 0) 269 if (length == 0)
263 break; 270 break;
264 271
265 if (* line == '\r') { 272 if (* line == '\r') {
266 line ++; 273 line ++;
267 274
268 count ++; 275 count ++;
269 length --; 276 length --;
270 277
271 if (* line == '\n') { 278 if (* line == '\n') {
272 line ++; 279 line ++;
273 280
274 count ++; 281 count ++;
275 length --; 282 length --;
276 283
277 break; 284 break;
278 } 285 }
279 } 286 }
280 287
281 if (* line == '\n') { 288 if (* line == '\n') {
282 line ++; 289 line ++;
283 290
284 count ++; 291 count ++;
285 length --; 292 length --;
286 293
287 fix_eol = 1; 294 fix_eol = 1;
288 break; 295 break;
289 } 296 }
290 297
291 line ++; 298 line ++;
292 length --; 299 length --;
293 count ++; 300 count ++;
294 } 301 }
295 302
296 if (start[0] == '.') 303 if (start[0] == '.')
297 if (mailstream_write(s, ".", 1) == -1) 304 if (mailstream_write(s, ".", 1) == -1)
298 goto err; 305 goto err;
299 306
300 if (fix_eol) { 307 if (fix_eol) {
301 if (mailstream_write(s, start, count - 1) == -1) 308 if (mailstream_write(s, start, count - 1) == -1)
302 goto err; 309 goto err;
303 if (mailstream_write(s, "\r\n", 2) == -1) 310 if (mailstream_write(s, "\r\n", 2) == -1)
304 goto err; 311 goto err;
305 } 312 }
306 else { 313 else {
307 if (mailstream_write(s, start, count) == -1) 314 if (mailstream_write(s, start, count) == -1)
308 goto err; 315 goto err;
309 } 316 }
310 317
311 318
312#if 0 319#if 0
313 while (* line != '\n') { 320 while (* line != '\n') {
314 if (* line == '\r') 321 if (* line == '\r')
315 pos = line; 322 pos = line;
316 if (* line == '\0') 323 if (* line == '\0')
317 return line; 324 return line;
318 if (mailstream_write(s, line, 1) == -1) 325 if (mailstream_write(s, line, 1) == -1)
319 goto err; 326 goto err;
320 line ++; 327 line ++;
321 } 328 }
322 if (pos + 1 == line) { 329 if (pos + 1 == line) {
323 if (mailstream_write(s, line, 1) == -1) 330 if (mailstream_write(s, line, 1) == -1)
324 goto err; 331 goto err;
325 } 332 }
326 else { 333 else {
327 if (mailstream_write(s, "\r\n", 2) == -1) 334 if (mailstream_write(s, "\r\n", 2) == -1)
328 goto err; 335 goto err;
329 } 336 }
330 line ++; 337 line ++;
331#endif 338#endif
332 339
333 return count; 340 return count;
334 341
335 err: 342 err:
336 return -1; 343 return -1;
337} 344}
338 345
339int mailstream_send_data(mailstream * s, const char * message, 346int mailstream_send_data(mailstream * s, const char * message,
340 size_t size, 347 size_t size,
341 size_t progr_rate, 348 size_t progr_rate,
342 progress_function * progr_fun) 349 progress_function * progr_fun)
343{ 350{
344 const char * current; 351 const char * current;
345 size_t count; 352 size_t count;
346 size_t last; 353 size_t last;
347 size_t remaining; 354 size_t remaining;
348 355
349 count = 0; 356 count = 0;
350 last = 0; 357 last = 0;
351 358
352 current = message; 359 current = message;
353 remaining = size; 360 remaining = size;
354 361
355 while (remaining > 0) { 362 while (remaining > 0) {
356 ssize_t length; 363 ssize_t length;
357 364
358 length = send_data_line(s, current, remaining); 365 length = send_data_line(s, current, remaining);
359 if (length < 0) 366 if (length < 0)
360 goto err; 367 goto err;
361 368
362 current += length; 369 current += length;
363 370
364 count += length; 371 count += length;
365 if ((progr_rate != 0) && (progr_fun != NULL)) 372 if ((progr_rate != 0) && (progr_fun != NULL))
366 if (count - last >= progr_rate) { 373 if (count - last >= progr_rate) {
367 (* progr_fun)(count, size); 374 (* progr_fun)(count, size);
368 last = count; 375 last = count;
369 } 376 }
370 377
371 remaining -= length; 378 remaining -= length;
372 } 379 }
373 if (mailstream_write(s, "\r\n.\r\n", 5) == -1) 380 if (mailstream_write(s, "\r\n.\r\n", 5) == -1)
374 goto err; 381 goto err;
375 382
376 if (mailstream_flush(s) == -1) 383 if (mailstream_flush(s) == -1)
377 goto err; 384 goto err;
378 385
379 return 0; 386 return 0;
380 387
381 err: 388 err:
382 return -1; 389 return -1;
383} 390}