summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/data-types/mailstream_helper.c11
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver.c8
-rw-r--r--libetpan/src/low-level/imap/mailimap_parser.c22
-rw-r--r--libetpan/src/low-level/maildir/maildir.c17
-rw-r--r--libetpan/src/low-level/mh/mailmh.c3
-rw-r--r--libetpan/src/low-level/pop3/mailpop3.c7
6 files changed, 59 insertions, 9 deletions
diff --git a/libetpan/src/data-types/mailstream_helper.c b/libetpan/src/data-types/mailstream_helper.c
index 2f0b9ae..f0ddf51 100644
--- a/libetpan/src/data-types/mailstream_helper.c
+++ b/libetpan/src/data-types/mailstream_helper.c
@@ -1,294 +1,301 @@
1/* 1/*
2 * libEtPan! -- a mail stuff library 2 * libEtPan! -- a mail stuff library
3 * 3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa 4 * Copyright (C) 2001, 2005 - 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 AUTHORS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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 inline ssize_t send_data_line(mailstream * s, 257static inline ssize_t send_data_line(mailstream * s,
251 const char * line, size_t length) 258 const char * line, size_t length)
252{ 259{
253 int fix_eol; 260 int fix_eol;
254 const char * start; 261 const char * start;
255 size_t count; 262 size_t count;
256 263
257 start = line; 264 start = line;
258 265
259 fix_eol = 0; 266 fix_eol = 0;
260 count = 0; 267 count = 0;
261 268
262 while (1) { 269 while (1) {
263 if (length == 0) 270 if (length == 0)
264 break; 271 break;
265 272
266 if (* line == '\r') { 273 if (* line == '\r') {
267 line ++; 274 line ++;
268 275
269 count ++; 276 count ++;
270 length --; 277 length --;
271 278
272 if (length == 0) { 279 if (length == 0) {
273 fix_eol = 1; 280 fix_eol = 1;
274 break; 281 break;
275 } 282 }
276 283
277 if (* line == '\n') { 284 if (* line == '\n') {
278 line ++; 285 line ++;
279 286
280 count ++; 287 count ++;
281 length --; 288 length --;
282 289
283 break; 290 break;
284 } 291 }
285 else { 292 else {
286 fix_eol = 1; 293 fix_eol = 1;
287 break; 294 break;
288 } 295 }
289 } 296 }
290 else if (* line == '\n') { 297 else if (* line == '\n') {
291 line ++; 298 line ++;
292 299
293 count ++; 300 count ++;
294 length --; 301 length --;
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver.c b/libetpan/src/driver/implementation/pop3/pop3driver.c
index ea69923..6cc6a9a 100644
--- a/libetpan/src/driver/implementation/pop3/pop3driver.c
+++ b/libetpan/src/driver/implementation/pop3/pop3driver.c
@@ -60,329 +60,335 @@ static int pop3driver_login(mailsession * session,
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 //LR
253 int ret;
252 carray * msg_tab; 254 carray * msg_tab;
253 struct pop3_session_state_data * data; 255 struct pop3_session_state_data * data;
254 256
255 data = get_data(session); 257 data = get_data(session);
256 258
257 switch (data->pop3_auth_type) { 259 switch (data->pop3_auth_type) {
258 case POP3DRIVER_AUTH_TYPE_TRY_APOP: 260 case POP3DRIVER_AUTH_TYPE_TRY_APOP:
259 r = mailpop3_login_apop(get_pop3_session(session), userid, password); 261 r = mailpop3_login_apop(get_pop3_session(session), userid, password);
260 if (r != MAILPOP3_NO_ERROR) 262 if (r != MAILPOP3_NO_ERROR)
261 r = mailpop3_login(get_pop3_session(session), userid, password); 263 r = mailpop3_login(get_pop3_session(session), userid, password);
262 break; 264 break;
263 265
264 case POP3DRIVER_AUTH_TYPE_APOP: 266 case POP3DRIVER_AUTH_TYPE_APOP:
265 r = mailpop3_login_apop(get_pop3_session(session), userid, password); 267 r = mailpop3_login_apop(get_pop3_session(session), userid, password);
266 break; 268 break;
267 269
268 default: 270 default:
269 case POP3DRIVER_AUTH_TYPE_PLAIN: 271 case POP3DRIVER_AUTH_TYPE_PLAIN:
270 r = mailpop3_login(get_pop3_session(session), userid, password); 272 r = mailpop3_login(get_pop3_session(session), userid, password);
271 break; 273 break;
272 } 274 }
273 275
274 mailpop3_list(get_pop3_session(session), &msg_tab); 276 // LR 2 lines
277 ret = pop3driver_pop3_error_to_mail_error(r);
278 if ( ret == MAIL_NO_ERROR )
279 mailpop3_list(get_pop3_session(session), &msg_tab);
280 // LR
275 281
276 return pop3driver_pop3_error_to_mail_error(r); 282 return pop3driver_pop3_error_to_mail_error(r);
277} 283}
278 284
279static int pop3driver_logout(mailsession * session) 285static int pop3driver_logout(mailsession * session)
280{ 286{
281 int r; 287 int r;
282 288
283 r = mailpop3_quit(get_pop3_session(session)); 289 r = mailpop3_quit(get_pop3_session(session));
284 290
285 return pop3driver_pop3_error_to_mail_error(r); 291 return pop3driver_pop3_error_to_mail_error(r);
286} 292}
287 293
288static int pop3driver_noop(mailsession * session) 294static int pop3driver_noop(mailsession * session)
289{ 295{
290 int r; 296 int r;
291 297
292 r = mailpop3_noop(get_pop3_session(session)); 298 r = mailpop3_noop(get_pop3_session(session));
293 299
294 return pop3driver_pop3_error_to_mail_error(r); 300 return pop3driver_pop3_error_to_mail_error(r);
295} 301}
296 302
297static int pop3driver_status_folder(mailsession * session, char * mb, 303static int pop3driver_status_folder(mailsession * session, char * mb,
298 uint32_t * result_messages, 304 uint32_t * result_messages,
299 uint32_t * result_recent, 305 uint32_t * result_recent,
300 uint32_t * result_unseen) 306 uint32_t * result_unseen)
301{ 307{
302 uint32_t count; 308 uint32_t count;
303 int r; 309 int r;
304 310
305 r = pop3driver_messages_number(session, mb, &count); 311 r = pop3driver_messages_number(session, mb, &count);
306 if (r != MAIL_NO_ERROR) 312 if (r != MAIL_NO_ERROR)
307 return r; 313 return r;
308 314
309 * result_messages = count; 315 * result_messages = count;
310 * result_recent = count; 316 * result_recent = count;
311 * result_unseen = count; 317 * result_unseen = count;
312 318
313 return MAIL_NO_ERROR; 319 return MAIL_NO_ERROR;
314} 320}
315 321
316static int pop3driver_messages_number(mailsession * session, char * mb, 322static int pop3driver_messages_number(mailsession * session, char * mb,
317 uint32_t * result) 323 uint32_t * result)
318{ 324{
319 carray * msg_tab; 325 carray * msg_tab;
320 326
321 mailpop3_list(get_pop3_session(session), &msg_tab); 327 mailpop3_list(get_pop3_session(session), &msg_tab);
322 328
323 * result = carray_count(msg_tab) - 329 * result = carray_count(msg_tab) -
324 get_pop3_session(session)->pop3_deleted_count; 330 get_pop3_session(session)->pop3_deleted_count;
325 331
326 return MAIL_NO_ERROR; 332 return MAIL_NO_ERROR;
327} 333}
328 334
329 335
330/* messages operations */ 336/* messages operations */
331 337
332static int pop3driver_remove_message(mailsession * session, uint32_t num) 338static int pop3driver_remove_message(mailsession * session, uint32_t num)
333{ 339{
334 mailpop3 * pop3; 340 mailpop3 * pop3;
335 int r; 341 int r;
336 342
337 pop3 = get_pop3_session(session); 343 pop3 = get_pop3_session(session);
338 344
339 r = mailpop3_dele(pop3, num); 345 r = mailpop3_dele(pop3, num);
340 switch (r) { 346 switch (r) {
341 case MAILPOP3_ERROR_BAD_STATE: 347 case MAILPOP3_ERROR_BAD_STATE:
342 return MAIL_ERROR_BAD_STATE; 348 return MAIL_ERROR_BAD_STATE;
343 349
344 case MAILPOP3_ERROR_NO_SUCH_MESSAGE: 350 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
345 return MAIL_ERROR_MSG_NOT_FOUND; 351 return MAIL_ERROR_MSG_NOT_FOUND;
346 352
347 case MAILPOP3_ERROR_STREAM: 353 case MAILPOP3_ERROR_STREAM:
348 return MAIL_ERROR_STREAM; 354 return MAIL_ERROR_STREAM;
349 355
350 case MAILPOP3_NO_ERROR: 356 case MAILPOP3_NO_ERROR:
351 return MAIL_NO_ERROR; 357 return MAIL_NO_ERROR;
352 358
353 default: 359 default:
354 return MAIL_ERROR_REMOVE; 360 return MAIL_ERROR_REMOVE;
355 } 361 }
356} 362}
357 363
358static int pop3driver_get_messages_list(mailsession * session, 364static int pop3driver_get_messages_list(mailsession * session,
359 struct mailmessage_list ** result) 365 struct mailmessage_list ** result)
360{ 366{
361 mailpop3 * pop3; 367 mailpop3 * pop3;
362 368
363 pop3 = get_pop3_session(session); 369 pop3 = get_pop3_session(session);
364 370
365 return pop3_get_messages_list(pop3, session, 371 return pop3_get_messages_list(pop3, session,
366 pop3_message_driver, result); 372 pop3_message_driver, result);
367} 373}
368 374
369static int pop3driver_get_message(mailsession * session, 375static int pop3driver_get_message(mailsession * session,
370 uint32_t num, mailmessage ** result) 376 uint32_t num, mailmessage ** result)
371{ 377{
372 mailmessage * msg_info; 378 mailmessage * msg_info;
373 int r; 379 int r;
374 380
375 msg_info = mailmessage_new(); 381 msg_info = mailmessage_new();
376 if (msg_info == NULL) 382 if (msg_info == NULL)
377 return MAIL_ERROR_MEMORY; 383 return MAIL_ERROR_MEMORY;
378 384
379 r = mailmessage_init(msg_info, session, pop3_message_driver, num, 0); 385 r = mailmessage_init(msg_info, session, pop3_message_driver, num, 0);
380 if (r != MAIL_NO_ERROR) { 386 if (r != MAIL_NO_ERROR) {
381 mailmessage_free(msg_info); 387 mailmessage_free(msg_info);
382 return r; 388 return r;
383 } 389 }
384 390
385 * result = msg_info; 391 * result = msg_info;
386 392
387 return MAIL_NO_ERROR; 393 return MAIL_NO_ERROR;
388} 394}
diff --git a/libetpan/src/low-level/imap/mailimap_parser.c b/libetpan/src/low-level/imap/mailimap_parser.c
index ab4db67..071891c 100644
--- a/libetpan/src/low-level/imap/mailimap_parser.c
+++ b/libetpan/src/low-level/imap/mailimap_parser.c
@@ -2210,386 +2210,404 @@ mailimap_body_fields_parse(mailstream * fd, MMAPString * buffer,
2210 * result = body_fields; 2210 * result = body_fields;
2211 * index = cur_token; 2211 * index = cur_token;
2212 2212
2213 return MAILIMAP_NO_ERROR; 2213 return MAILIMAP_NO_ERROR;
2214 2214
2215 fld_enc_free: 2215 fld_enc_free:
2216 mailimap_body_fld_enc_free(body_fld_enc); 2216 mailimap_body_fld_enc_free(body_fld_enc);
2217 fld_desc_free: 2217 fld_desc_free:
2218 mailimap_body_fld_desc_free(body_fld_desc); 2218 mailimap_body_fld_desc_free(body_fld_desc);
2219 fld_id_free: 2219 fld_id_free:
2220 mailimap_body_fld_id_free(body_fld_id); 2220 mailimap_body_fld_id_free(body_fld_id);
2221 fld_param_free: 2221 fld_param_free:
2222 if (body_fld_param != NULL) 2222 if (body_fld_param != NULL)
2223 mailimap_body_fld_param_free(body_fld_param); 2223 mailimap_body_fld_param_free(body_fld_param);
2224 err: 2224 err:
2225 return res; 2225 return res;
2226} 2226}
2227 2227
2228/* 2228/*
2229 body-fld-desc = nstring 2229 body-fld-desc = nstring
2230*/ 2230*/
2231 2231
2232static int mailimap_body_fld_desc_parse(mailstream * fd, MMAPString * buffer, 2232static int mailimap_body_fld_desc_parse(mailstream * fd, MMAPString * buffer,
2233 size_t * index, char ** result, 2233 size_t * index, char ** result,
2234 size_t progr_rate, 2234 size_t progr_rate,
2235 progress_function * progr_fun) 2235 progress_function * progr_fun)
2236{ 2236{
2237 return mailimap_nstring_parse(fd, buffer, index, result, NULL, 2237 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
2238 progr_rate, progr_fun); 2238 progr_rate, progr_fun);
2239} 2239}
2240 2240
2241/* 2241/*
2242 body-fld-dsp = "(" string SP body-fld-param ")" / nil 2242 body-fld-dsp = "(" string SP body-fld-param ")" / nil
2243*/ 2243*/
2244 2244
2245static int 2245static int
2246mailimap_body_fld_dsp_parse(mailstream * fd, MMAPString * buffer, 2246mailimap_body_fld_dsp_parse(mailstream * fd, MMAPString * buffer,
2247 size_t * index, 2247 size_t * index,
2248 struct mailimap_body_fld_dsp ** result, 2248 struct mailimap_body_fld_dsp ** result,
2249 size_t progr_rate, 2249 size_t progr_rate,
2250 progress_function * progr_fun) 2250 progress_function * progr_fun)
2251{ 2251{
2252 size_t cur_token; 2252 size_t cur_token;
2253 char * name; 2253 char * name;
2254 struct mailimap_body_fld_param * body_fld_param; 2254 struct mailimap_body_fld_param * body_fld_param;
2255 struct mailimap_body_fld_dsp * body_fld_dsp; 2255 struct mailimap_body_fld_dsp * body_fld_dsp;
2256 int res; 2256 int res;
2257 int r; 2257 int r;
2258 2258
2259 cur_token = * index; 2259 cur_token = * index;
2260 name = NULL; 2260 name = NULL;
2261 body_fld_param = NULL; 2261 body_fld_param = NULL;
2262 2262
2263 r = mailimap_nil_parse(fd, buffer, &cur_token); 2263 r = mailimap_nil_parse(fd, buffer, &cur_token);
2264 if (r == MAILIMAP_NO_ERROR) { 2264 if (r == MAILIMAP_NO_ERROR) {
2265 * result = NULL; 2265 * result = NULL;
2266 * index = cur_token; 2266 * index = cur_token;
2267 return MAILIMAP_NO_ERROR; 2267 return MAILIMAP_NO_ERROR;
2268 } 2268 }
2269 2269
2270 if (r != MAILIMAP_ERROR_PARSE) { 2270 if (r != MAILIMAP_ERROR_PARSE) {
2271 res = r; 2271 res = r;
2272 goto err; 2272 goto err;
2273 } 2273 }
2274 2274
2275 r = mailimap_oparenth_parse(fd, buffer, &cur_token); 2275 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
2276 if (r != MAILIMAP_NO_ERROR) { 2276 if (r != MAILIMAP_NO_ERROR) {
2277 res = r; 2277 res = r;
2278 goto err; 2278 goto err;
2279 } 2279 }
2280 2280
2281 r = mailimap_string_parse(fd, buffer, &cur_token, &name, NULL, 2281 r = mailimap_string_parse(fd, buffer, &cur_token, &name, NULL,
2282 progr_rate, progr_fun); 2282 progr_rate, progr_fun);
2283 if (r != MAILIMAP_NO_ERROR) { 2283 if (r != MAILIMAP_NO_ERROR) {
2284 res = r; 2284 res = r;
2285 goto err; 2285 goto err;
2286 } 2286 }
2287 2287
2288 r = mailimap_space_parse(fd, buffer, &cur_token); 2288 r = mailimap_space_parse(fd, buffer, &cur_token);
2289 if (r != MAILIMAP_NO_ERROR) { 2289 if (r != MAILIMAP_NO_ERROR) {
2290 res = r; 2290 res = r;
2291 goto string_free; 2291 goto string_free;
2292 } 2292 }
2293 2293
2294 r = mailimap_body_fld_param_parse(fd, buffer, &cur_token, 2294 r = mailimap_body_fld_param_parse(fd, buffer, &cur_token,
2295 &body_fld_param, 2295 &body_fld_param,
2296 progr_rate, progr_fun); 2296 progr_rate, progr_fun);
2297 if (r != MAILIMAP_NO_ERROR) { 2297 if (r != MAILIMAP_NO_ERROR) {
2298 res = r; 2298 res = r;
2299 goto string_free; 2299 goto string_free;
2300 } 2300 }
2301 2301
2302 r = mailimap_cparenth_parse(fd, buffer, &cur_token); 2302 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
2303 if (r != MAILIMAP_NO_ERROR) { 2303 if (r != MAILIMAP_NO_ERROR) {
2304 res = r; 2304 res = r;
2305 goto string_free; 2305 goto string_free;
2306 } 2306 }
2307 2307
2308 body_fld_dsp = mailimap_body_fld_dsp_new(name, body_fld_param); 2308 body_fld_dsp = mailimap_body_fld_dsp_new(name, body_fld_param);
2309 if (body_fld_dsp == NULL) { 2309 if (body_fld_dsp == NULL) {
2310 res = MAILIMAP_ERROR_MEMORY; 2310 res = MAILIMAP_ERROR_MEMORY;
2311 goto fld_param_free; 2311 goto fld_param_free;
2312 } 2312 }
2313 2313
2314 * index = cur_token; 2314 * index = cur_token;
2315 * result = body_fld_dsp; 2315 * result = body_fld_dsp;
2316 2316
2317 return MAILIMAP_NO_ERROR; 2317 return MAILIMAP_NO_ERROR;
2318 2318
2319 fld_param_free: 2319 fld_param_free:
2320 if (body_fld_param != NULL) 2320 if (body_fld_param != NULL)
2321 mailimap_body_fld_param_free(body_fld_param); 2321 mailimap_body_fld_param_free(body_fld_param);
2322 string_free: 2322 string_free:
2323 mailimap_string_free(name); 2323 mailimap_string_free(name);
2324 err: 2324 err:
2325 return res; 2325 return res;
2326} 2326}
2327 2327
2328/* 2328/*
2329 body-fld-enc = (DQUOTE ("7BIT" / "8BIT" / "BINARY" / "BASE64"/ 2329 body-fld-enc = (DQUOTE ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
2330 "QUOTED-PRINTABLE") DQUOTE) / string 2330 "QUOTED-PRINTABLE") DQUOTE) / string
2331*/ 2331*/
2332 2332
2333static inline int 2333static inline int
2334mailimap_body_fld_known_enc_parse(mailstream * fd, MMAPString * buffer, 2334mailimap_body_fld_known_enc_parse(mailstream * fd, MMAPString * buffer,
2335 size_t * index, 2335 size_t * index,
2336 int * result, 2336 int * result,
2337 size_t progr_rate, 2337 size_t progr_rate,
2338 progress_function * progr_fun) 2338 progress_function * progr_fun)
2339{ 2339{
2340 size_t cur_token; 2340 size_t cur_token;
2341 int type; 2341 int type;
2342 int r; 2342 int r;
2343 int res; 2343 int res;
2344 2344
2345 cur_token = * index; 2345 cur_token = * index;
2346 2346
2347 r = mailimap_dquote_parse(fd, buffer, &cur_token); 2347 r = mailimap_dquote_parse(fd, buffer, &cur_token);
2348 if (r != MAILIMAP_NO_ERROR) { 2348 if (r != MAILIMAP_NO_ERROR) {
2349 res = r; 2349 res = r;
2350 goto err; 2350 goto err;
2351 } 2351 }
2352 2352
2353 type = mailimap_encoding_get_token_value(fd, buffer, &cur_token); 2353 type = mailimap_encoding_get_token_value(fd, buffer, &cur_token);
2354 2354
2355 if (type == -1) { 2355 if (type == -1) {
2356 res = MAILIMAP_ERROR_PARSE; 2356 res = MAILIMAP_ERROR_PARSE;
2357 goto err; 2357 goto err;
2358 } 2358 }
2359 2359
2360 r = mailimap_dquote_parse(fd, buffer, &cur_token); 2360 r = mailimap_dquote_parse(fd, buffer, &cur_token);
2361 if (r != MAILIMAP_NO_ERROR) { 2361 if (r != MAILIMAP_NO_ERROR) {
2362 res = r; 2362 res = r;
2363 goto err; 2363 goto err;
2364 } 2364 }
2365 2365
2366 * result = type; 2366 * result = type;
2367 * index = cur_token; 2367 * index = cur_token;
2368 2368
2369 return MAILIMAP_NO_ERROR; 2369 return MAILIMAP_NO_ERROR;
2370 2370
2371 err: 2371 err:
2372 return res; 2372 return res;
2373} 2373}
2374 2374
2375static int 2375static int
2376mailimap_body_fld_enc_parse(mailstream * fd, MMAPString * buffer, 2376mailimap_body_fld_enc_parse(mailstream * fd, MMAPString * buffer,
2377 size_t * index, 2377 size_t * index,
2378 struct mailimap_body_fld_enc ** result, 2378 struct mailimap_body_fld_enc ** result,
2379 size_t progr_rate, 2379 size_t progr_rate,
2380 progress_function * progr_fun) 2380 progress_function * progr_fun)
2381{ 2381{
2382 size_t cur_token; 2382 size_t cur_token;
2383 int type; 2383 int type;
2384 char * value; 2384 char * value;
2385 struct mailimap_body_fld_enc * body_fld_enc; 2385 struct mailimap_body_fld_enc * body_fld_enc;
2386 int r; 2386 int r;
2387 int res; 2387 int res;
2388 2388
2389 cur_token = * index; 2389 cur_token = * index;
2390 2390
2391 r = mailimap_body_fld_known_enc_parse(fd, buffer, &cur_token, 2391 r = mailimap_body_fld_known_enc_parse(fd, buffer, &cur_token,
2392 &type, progr_rate, progr_fun); 2392 &type, progr_rate, progr_fun);
2393 if (r == MAILIMAP_NO_ERROR) { 2393 if (r == MAILIMAP_NO_ERROR) {
2394 value = NULL; 2394 value = NULL;
2395 } 2395 }
2396 else if (r == MAILIMAP_ERROR_PARSE) { 2396 else if (r == MAILIMAP_ERROR_PARSE) {
2397 type = MAILIMAP_BODY_FLD_ENC_OTHER; 2397 type = MAILIMAP_BODY_FLD_ENC_OTHER;
2398 2398
2399 r = mailimap_string_parse(fd, buffer, &cur_token, &value, NULL, 2399 r = mailimap_string_parse(fd, buffer, &cur_token, &value, NULL,
2400 progr_rate, progr_fun); 2400 progr_rate, progr_fun);
2401 if (r != MAILIMAP_NO_ERROR) { 2401 if (r != MAILIMAP_NO_ERROR) {
2402 res = r; 2402 // LR start
2403 goto err; 2403 // accept NIL and set type to utf8
2404 int ret = r;
2405 r = mailimap_char_parse(fd, buffer, &cur_token, 'N');
2406 if (r == MAILIMAP_NO_ERROR) {
2407 r = mailimap_char_parse(fd, buffer, &cur_token, 'I');
2408 if (r == MAILIMAP_NO_ERROR) {
2409 r = mailimap_char_parse(fd, buffer, &cur_token, 'L');
2410 if (r == MAILIMAP_NO_ERROR) {
2411 type = 4;
2412 ret = MAILIMAP_NO_ERROR;
2413 value = NULL;
2414 }
2415 }
2416 }
2417 if ( ret != MAILIMAP_NO_ERROR ) {
2418 res = ret;
2419 goto err;
2420 }
2421 // LR end
2404 } 2422 }
2405 } 2423 }
2406 else { 2424 else {
2407 res = r; 2425 res = r;
2408 goto err; 2426 goto err;
2409 } 2427 }
2410 2428
2411 body_fld_enc = mailimap_body_fld_enc_new(type, value); 2429 body_fld_enc = mailimap_body_fld_enc_new(type, value);
2412 if (body_fld_enc == NULL) { 2430 if (body_fld_enc == NULL) {
2413 res = MAILIMAP_ERROR_MEMORY; 2431 res = MAILIMAP_ERROR_MEMORY;
2414 goto value_free; 2432 goto value_free;
2415 } 2433 }
2416 2434
2417 * result = body_fld_enc; 2435 * result = body_fld_enc;
2418 * index = cur_token; 2436 * index = cur_token;
2419 2437
2420 return MAILIMAP_NO_ERROR; 2438 return MAILIMAP_NO_ERROR;
2421 2439
2422 value_free: 2440 value_free:
2423 if (value) 2441 if (value)
2424 mailimap_string_free(value); 2442 mailimap_string_free(value);
2425 err: 2443 err:
2426 return res; 2444 return res;
2427} 2445}
2428 2446
2429/* 2447/*
2430 body-fld-id = nstring 2448 body-fld-id = nstring
2431*/ 2449*/
2432 2450
2433static int mailimap_body_fld_id_parse(mailstream * fd, MMAPString * buffer, 2451static int mailimap_body_fld_id_parse(mailstream * fd, MMAPString * buffer,
2434 size_t * index, char ** result, 2452 size_t * index, char ** result,
2435 size_t progr_rate, 2453 size_t progr_rate,
2436 progress_function * progr_fun) 2454 progress_function * progr_fun)
2437{ 2455{
2438 return mailimap_nstring_parse(fd, buffer, index, result, NULL, 2456 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
2439 progr_rate, progr_fun); 2457 progr_rate, progr_fun);
2440} 2458}
2441 2459
2442 2460
2443/* 2461/*
2444 body-fld-lang = nstring / "(" string *(SP string) ")" 2462 body-fld-lang = nstring / "(" string *(SP string) ")"
2445*/ 2463*/
2446 2464
2447/* 2465/*
2448"(" string *(SP string) ")" 2466"(" string *(SP string) ")"
2449*/ 2467*/
2450 2468
2451static int 2469static int
2452mailimap_body_fld_lang_list_parse(mailstream * fd, MMAPString * buffer, 2470mailimap_body_fld_lang_list_parse(mailstream * fd, MMAPString * buffer,
2453 size_t * index, clist ** result, 2471 size_t * index, clist ** result,
2454 size_t progr_rate, 2472 size_t progr_rate,
2455 progress_function * progr_fun) 2473 progress_function * progr_fun)
2456{ 2474{
2457 size_t cur_token; 2475 size_t cur_token;
2458 clist * list; 2476 clist * list;
2459 int r; 2477 int r;
2460 int res; 2478 int res;
2461 2479
2462 cur_token = * index; 2480 cur_token = * index;
2463 2481
2464 r = mailimap_oparenth_parse(fd, buffer, &cur_token); 2482 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
2465 if (r != MAILIMAP_NO_ERROR) { 2483 if (r != MAILIMAP_NO_ERROR) {
2466 res = r; 2484 res = r;
2467 goto err; 2485 goto err;
2468 } 2486 }
2469 2487
2470 list = clist_new(); 2488 list = clist_new();
2471 if (list == NULL) { 2489 if (list == NULL) {
2472 res = MAILIMAP_ERROR_MEMORY; 2490 res = MAILIMAP_ERROR_MEMORY;
2473 goto err; 2491 goto err;
2474 } 2492 }
2475 2493
2476 while (1) { 2494 while (1) {
2477 char * elt; 2495 char * elt;
2478 2496
2479 r = mailimap_string_parse(fd, buffer, &cur_token, &elt, NULL, 2497 r = mailimap_string_parse(fd, buffer, &cur_token, &elt, NULL,
2480 progr_rate, progr_fun); 2498 progr_rate, progr_fun);
2481 if (r != MAILIMAP_ERROR_PARSE) 2499 if (r != MAILIMAP_ERROR_PARSE)
2482 break; 2500 break;
2483 else if (r == MAILIMAP_NO_ERROR) { 2501 else if (r == MAILIMAP_NO_ERROR) {
2484 r = clist_append(list, elt); 2502 r = clist_append(list, elt);
2485 if (r < 0) { 2503 if (r < 0) {
2486 mailimap_string_free(elt); 2504 mailimap_string_free(elt);
2487 res = r; 2505 res = r;
2488 goto list_free; 2506 goto list_free;
2489 } 2507 }
2490 } 2508 }
2491 else { 2509 else {
2492 res = r; 2510 res = r;
2493 goto list_free; 2511 goto list_free;
2494 } 2512 }
2495 } 2513 }
2496 2514
2497 r = mailimap_cparenth_parse(fd, buffer, &cur_token); 2515 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
2498 if (r != MAILIMAP_NO_ERROR) { 2516 if (r != MAILIMAP_NO_ERROR) {
2499 res = r; 2517 res = r;
2500 goto list_free; 2518 goto list_free;
2501 } 2519 }
2502 2520
2503 * index = cur_token; 2521 * index = cur_token;
2504 * result = list; 2522 * result = list;
2505 2523
2506 return MAILIMAP_NO_ERROR; 2524 return MAILIMAP_NO_ERROR;
2507 2525
2508 list_free: 2526 list_free:
2509 clist_foreach(list, (clist_func) mailimap_string_free, NULL); 2527 clist_foreach(list, (clist_func) mailimap_string_free, NULL);
2510 clist_free(list); 2528 clist_free(list);
2511 err: 2529 err:
2512 return res; 2530 return res;
2513} 2531}
2514 2532
2515/* 2533/*
2516 body-fld-lang = nstring / "(" string *(SP string) ")" 2534 body-fld-lang = nstring / "(" string *(SP string) ")"
2517*/ 2535*/
2518 2536
2519static int 2537static int
2520mailimap_body_fld_lang_parse(mailstream * fd, MMAPString * buffer, 2538mailimap_body_fld_lang_parse(mailstream * fd, MMAPString * buffer,
2521 size_t * index, 2539 size_t * index,
2522 struct mailimap_body_fld_lang ** result, 2540 struct mailimap_body_fld_lang ** result,
2523 size_t progr_rate, 2541 size_t progr_rate,
2524 progress_function * progr_fun) 2542 progress_function * progr_fun)
2525{ 2543{
2526 char * value; 2544 char * value;
2527 clist * list; 2545 clist * list;
2528 struct mailimap_body_fld_lang * fld_lang; 2546 struct mailimap_body_fld_lang * fld_lang;
2529 int type; 2547 int type;
2530 int r; 2548 int r;
2531 int res; 2549 int res;
2532 2550
2533 size_t cur_token; 2551 size_t cur_token;
2534 2552
2535 cur_token = * index; 2553 cur_token = * index;
2536 2554
2537 value = NULL; 2555 value = NULL;
2538 list = NULL; 2556 list = NULL;
2539 type = MAILIMAP_BODY_FLD_LANG_ERROR; /* XXX - removes a gcc warning */ 2557 type = MAILIMAP_BODY_FLD_LANG_ERROR; /* XXX - removes a gcc warning */
2540 2558
2541 r = mailimap_nstring_parse(fd, buffer, &cur_token, &value, NULL, 2559 r = mailimap_nstring_parse(fd, buffer, &cur_token, &value, NULL,
2542 progr_rate, progr_fun); 2560 progr_rate, progr_fun);
2543 if (r == MAILIMAP_NO_ERROR) 2561 if (r == MAILIMAP_NO_ERROR)
2544 type = MAILIMAP_BODY_FLD_LANG_SINGLE; 2562 type = MAILIMAP_BODY_FLD_LANG_SINGLE;
2545 2563
2546 if (r == MAILIMAP_ERROR_PARSE) { 2564 if (r == MAILIMAP_ERROR_PARSE) {
2547 r = mailimap_body_fld_lang_list_parse(fd, buffer, &cur_token, &list, 2565 r = mailimap_body_fld_lang_list_parse(fd, buffer, &cur_token, &list,
2548 progr_rate, progr_fun); 2566 progr_rate, progr_fun);
2549 if (r == MAILIMAP_NO_ERROR) 2567 if (r == MAILIMAP_NO_ERROR)
2550 type = MAILIMAP_BODY_FLD_LANG_LIST; 2568 type = MAILIMAP_BODY_FLD_LANG_LIST;
2551 } 2569 }
2552 2570
2553 if (r != MAILIMAP_NO_ERROR) { 2571 if (r != MAILIMAP_NO_ERROR) {
2554 res = r; 2572 res = r;
2555 goto err; 2573 goto err;
2556 } 2574 }
2557 2575
2558 fld_lang = mailimap_body_fld_lang_new(type, value, list); 2576 fld_lang = mailimap_body_fld_lang_new(type, value, list);
2559 if (fld_lang == NULL) { 2577 if (fld_lang == NULL) {
2560 res = MAILIMAP_ERROR_MEMORY; 2578 res = MAILIMAP_ERROR_MEMORY;
2561 goto free; 2579 goto free;
2562 } 2580 }
2563 2581
2564 * index = cur_token; 2582 * index = cur_token;
2565 * result = fld_lang; 2583 * result = fld_lang;
2566 2584
2567 return MAILIMAP_NO_ERROR; 2585 return MAILIMAP_NO_ERROR;
2568 2586
2569 free: 2587 free:
2570 if (value) 2588 if (value)
2571 mailimap_nstring_free(value); 2589 mailimap_nstring_free(value);
2572 if (list) { 2590 if (list) {
2573 clist_foreach(list, (clist_func) mailimap_string_free, NULL); 2591 clist_foreach(list, (clist_func) mailimap_string_free, NULL);
2574 clist_free(list); 2592 clist_free(list);
2575 } 2593 }
2576 err: 2594 err:
2577 return res; 2595 return res;
2578} 2596}
2579 2597
2580/* 2598/*
2581 body-fld-lines = number 2599 body-fld-lines = number
2582*/ 2600*/
2583 2601
2584static int mailimap_body_fld_lines_parse(mailstream * fd, 2602static int mailimap_body_fld_lines_parse(mailstream * fd,
2585 MMAPString * buffer, size_t * index, 2603 MMAPString * buffer, size_t * index,
2586 uint32_t * result) 2604 uint32_t * result)
2587{ 2605{
2588 return mailimap_number_parse(fd, buffer, index, result); 2606 return mailimap_number_parse(fd, buffer, index, result);
2589} 2607}
2590 2608
2591/* 2609/*
2592 body-fld-md5 = nstring 2610 body-fld-md5 = nstring
2593*/ 2611*/
2594 2612
2595static int mailimap_body_fld_md5_parse(mailstream * fd, MMAPString * buffer, 2613static int mailimap_body_fld_md5_parse(mailstream * fd, MMAPString * buffer,
diff --git a/libetpan/src/low-level/maildir/maildir.c b/libetpan/src/low-level/maildir/maildir.c
index 98b9f87..e81625d 100644
--- a/libetpan/src/low-level/maildir/maildir.c
+++ b/libetpan/src/low-level/maildir/maildir.c
@@ -1,342 +1,355 @@
1/* 1/*
2 * libEtPan! -- a mail stuff library 2 * libEtPan! -- a mail stuff library
3 * 3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa 4 * Copyright (C) 2001, 2005 - 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 AUTHORS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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 "maildir.h" 36#include "maildir.h"
37 37
38#include <string.h> 38#include <string.h>
39#include <stdlib.h> 39#include <stdlib.h>
40#include <stdio.h> 40#include <stdio.h>
41#include <unistd.h> 41#include <unistd.h>
42#include <sys/types.h> 42#include <sys/types.h>
43#include <dirent.h> 43#include <dirent.h>
44#include <time.h> 44#include <time.h>
45#include <sys/stat.h> 45#include <sys/stat.h>
46#include <sys/mman.h> 46#include <sys/mman.h>
47#include <errno.h> 47#include <errno.h>
48#include <fcntl.h> 48#include <fcntl.h>
49 49
50#ifdef LIBETPAN_SYSTEM_BASENAME 50#ifdef LIBETPAN_SYSTEM_BASENAME
51#include <libgen.h> 51#include <libgen.h>
52#endif 52#endif
53 53
54/* 54/*
55 We suppose the maildir mailbox remains on one unique filesystem. 55 We suppose the maildir mailbox remains on one unique filesystem.
56*/ 56*/
57 57
58struct maildir * maildir_new(const char * path) 58struct maildir * maildir_new(const char * path)
59{ 59{
60 struct maildir * md; 60 struct maildir * md;
61 61
62 md = malloc(sizeof(* md)); 62 md = malloc(sizeof(* md));
63 if (md == NULL) 63 if (md == NULL)
64 goto err; 64 goto err;
65 65
66 md->mdir_counter = 0; 66 md->mdir_counter = 0;
67 md->mdir_mtime_new = (time_t) -1; 67 md->mdir_mtime_new = (time_t) -1;
68 md->mdir_mtime_cur = (time_t) -1; 68 md->mdir_mtime_cur = (time_t) -1;
69 69
70 md->mdir_pid = getpid(); 70 md->mdir_pid = getpid();
71 gethostname(md->mdir_hostname, sizeof(md->mdir_hostname)); 71 gethostname(md->mdir_hostname, sizeof(md->mdir_hostname));
72 strncpy(md->mdir_path, path, sizeof(md->mdir_path)); 72 strncpy(md->mdir_path, path, sizeof(md->mdir_path));
73 md->mdir_path[PATH_MAX - 1] = '\0'; 73 md->mdir_path[PATH_MAX - 1] = '\0';
74 74
75 md->mdir_msg_list = carray_new(128); 75 md->mdir_msg_list = carray_new(128);
76 if (md->mdir_msg_list == NULL) 76 if (md->mdir_msg_list == NULL)
77 goto free; 77 goto free;
78 78
79 md->mdir_msg_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE); 79 md->mdir_msg_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE);
80 if (md->mdir_msg_hash == NULL) 80 if (md->mdir_msg_hash == NULL)
81 goto free_msg_list; 81 goto free_msg_list;
82 82
83 return md; 83 return md;
84 84
85 free_msg_list: 85 free_msg_list:
86 carray_free(md->mdir_msg_list); 86 carray_free(md->mdir_msg_list);
87 free: 87 free:
88 free(md); 88 free(md);
89 err: 89 err:
90 return NULL; 90 return NULL;
91} 91}
92 92
93static void maildir_flush(struct maildir * md, int msg_new); 93static void maildir_flush(struct maildir * md, int msg_new);
94 94
95void maildir_free(struct maildir * md) 95void maildir_free(struct maildir * md)
96{ 96{
97 maildir_flush(md, 0); 97 maildir_flush(md, 0);
98 maildir_flush(md, 1); 98 maildir_flush(md, 1);
99 chash_free(md->mdir_msg_hash); 99 chash_free(md->mdir_msg_hash);
100 carray_free(md->mdir_msg_list); 100 carray_free(md->mdir_msg_list);
101 free(md); 101 free(md);
102} 102}
103 103
104#define MAX_TRY_ALLOC 32 104#define MAX_TRY_ALLOC 32
105 105
106static char * maildir_get_new_message_filename(struct maildir * md, 106static char * maildir_get_new_message_filename(struct maildir * md,
107 char * tmpfile) 107 char * tmpfile)
108{ 108{
109 char filename[PATH_MAX]; 109 char filename[PATH_MAX];
110 char basename[PATH_MAX]; 110 char basename[PATH_MAX];
111 int k; 111 int k;
112 time_t now; 112 time_t now;
113 //LR
114 struct stat f_stat;
113 int got_file; 115 int got_file;
114 int r; 116 int r;
115 117
116 got_file = 0; 118 got_file = 0;
117 now = time(NULL); 119 now = time(NULL);
118 k = 0; 120 k = 0;
119 while (k < MAX_TRY_ALLOC) { 121 while (k < MAX_TRY_ALLOC) {
120 snprintf(basename, sizeof(basename), "%lu.%u_%u.%s", 122 snprintf(basename, sizeof(basename), "%lu.%u_%u.%s",
121 (unsigned long) now, md->mdir_pid, md->mdir_counter, md->mdir_hostname); 123 (unsigned long) now, md->mdir_pid, md->mdir_counter, md->mdir_hostname);
122 snprintf(filename, sizeof(filename), "%s/tmp/%s", 124 snprintf(filename, sizeof(filename), "%s/tmp/%s",
123 md->mdir_path, basename); 125 md->mdir_path, basename);
124 126
127 // LR changed following lines
128 if ( stat( filename, &f_stat ) == -1 ) {
129 char * dup_filename;
130
131 dup_filename = strdup(filename);
132 if (dup_filename == NULL) {
133 //unlink(filename);
134 return NULL;
135 }
136 rename (tmpfile,dup_filename );
137#if 0
125 if (link(tmpfile, filename) == 0) { 138 if (link(tmpfile, filename) == 0) {
126 got_file = 1; 139 got_file = 1;
127 unlink(tmpfile); 140 unlink(tmpfile);
128 } 141 }
129 else if (errno == EXDEV) { 142 else if (errno == EXDEV) {
130 unlink(tmpfile); 143 unlink(tmpfile);
131 return NULL; 144 return NULL;
132 } 145 }
133 else if (errno == EPERM) { 146 else if (errno == EPERM) {
134 r = rename(tmpfile, filename); 147 r = rename(tmpfile, filename);
135 if (r < 0) { 148 if (r < 0) {
136 unlink(tmpfile); 149 unlink(tmpfile);
137 return NULL; 150 return NULL;
138 } 151 }
139 got_file = 1; 152 got_file = 1;
140 } 153 }
141 154
142 if (got_file) { 155 if (got_file) {
143 char * dup_filename; 156 char * dup_filename;
144 157
145 dup_filename = strdup(filename); 158 dup_filename = strdup(filename);
146 if (dup_filename == NULL) { 159 if (dup_filename == NULL) {
147 unlink(filename); 160 unlink(filename);
148 return NULL; 161 return NULL;
149 } 162 }
150 163#endif
151 md->mdir_counter ++; 164 md->mdir_counter ++;
152 165
153 return dup_filename; 166 return dup_filename;
154 } 167 }
155 168
156 md->mdir_counter ++; 169 md->mdir_counter ++;
157 k ++; 170 k ++;
158 } 171 }
159 172
160 return NULL; 173 return NULL;
161} 174}
162 175
163 176
164static void msg_free(struct maildir_msg * msg) 177static void msg_free(struct maildir_msg * msg)
165{ 178{
166 free(msg->msg_uid); 179 free(msg->msg_uid);
167 free(msg->msg_filename); 180 free(msg->msg_filename);
168 free(msg); 181 free(msg);
169} 182}
170 183
171/* 184/*
172 msg_new() 185 msg_new()
173 186
174 filename is given without path 187 filename is given without path
175*/ 188*/
176 189
177static struct maildir_msg * msg_new(char * filename, int new_msg) 190static struct maildir_msg * msg_new(char * filename, int new_msg)
178{ 191{
179 struct maildir_msg * msg; 192 struct maildir_msg * msg;
180 char * p; 193 char * p;
181 int flags; 194 int flags;
182 size_t uid_len; 195 size_t uid_len;
183 char * begin_uid; 196 char * begin_uid;
184 197
185 /* name of file : xxx-xxx_xxx-xxx:2,SRFT */ 198 /* name of file : xxx-xxx_xxx-xxx:2,SRFT */
186 199
187 msg = malloc(sizeof(* msg)); 200 msg = malloc(sizeof(* msg));
188 if (msg == NULL) 201 if (msg == NULL)
189 goto err; 202 goto err;
190 203
191 msg->msg_filename = strdup(filename); 204 msg->msg_filename = strdup(filename);
192 if (msg->msg_filename == NULL) 205 if (msg->msg_filename == NULL)
193 goto free; 206 goto free;
194 207
195 begin_uid = filename; 208 begin_uid = filename;
196 209
197 uid_len = strlen(begin_uid); 210 uid_len = strlen(begin_uid);
198 211
199 flags = 0; 212 flags = 0;
200 p = strstr(filename, ":2,"); 213 p = strstr(filename, ":2,");
201 if (p != NULL) { 214 if (p != NULL) {
202 uid_len = p - begin_uid; 215 uid_len = p - begin_uid;
203 216
204 p += 3; 217 p += 3;
205 218
206 /* parse flags */ 219 /* parse flags */
207 while (* p != '\0') { 220 while (* p != '\0') {
208 switch (* p) { 221 switch (* p) {
209 case 'S': 222 case 'S':
210 flags |= MAILDIR_FLAG_SEEN; 223 flags |= MAILDIR_FLAG_SEEN;
211 break; 224 break;
212 case 'R': 225 case 'R':
213 flags |= MAILDIR_FLAG_REPLIED; 226 flags |= MAILDIR_FLAG_REPLIED;
214 break; 227 break;
215 case 'F': 228 case 'F':
216 flags |= MAILDIR_FLAG_FLAGGED; 229 flags |= MAILDIR_FLAG_FLAGGED;
217 break; 230 break;
218 case 'T': 231 case 'T':
219 flags |= MAILDIR_FLAG_TRASHED; 232 flags |= MAILDIR_FLAG_TRASHED;
220 break; 233 break;
221 } 234 }
222 p ++; 235 p ++;
223 } 236 }
224 } 237 }
225 238
226 if (new_msg) 239 if (new_msg)
227 flags |= MAILDIR_FLAG_NEW; 240 flags |= MAILDIR_FLAG_NEW;
228 241
229 msg->msg_flags = flags; 242 msg->msg_flags = flags;
230 243
231 msg->msg_uid = malloc(uid_len + 1); 244 msg->msg_uid = malloc(uid_len + 1);
232 if (msg->msg_uid == NULL) 245 if (msg->msg_uid == NULL)
233 goto free_filename; 246 goto free_filename;
234 247
235 strncpy(msg->msg_uid, begin_uid, uid_len); 248 strncpy(msg->msg_uid, begin_uid, uid_len);
236 msg->msg_uid[uid_len] = '\0'; 249 msg->msg_uid[uid_len] = '\0';
237 250
238 return msg; 251 return msg;
239 252
240 free_filename: 253 free_filename:
241 free(msg->msg_filename); 254 free(msg->msg_filename);
242 free: 255 free:
243 free(msg); 256 free(msg);
244 err: 257 err:
245 return NULL; 258 return NULL;
246} 259}
247 260
248static void maildir_flush(struct maildir * md, int msg_new) 261static void maildir_flush(struct maildir * md, int msg_new)
249{ 262{
250 unsigned int i; 263 unsigned int i;
251 264
252 i = 0; 265 i = 0;
253 while (i < carray_count(md->mdir_msg_list)) { 266 while (i < carray_count(md->mdir_msg_list)) {
254 struct maildir_msg * msg; 267 struct maildir_msg * msg;
255 int delete; 268 int delete;
256 269
257 msg = carray_get(md->mdir_msg_list, i); 270 msg = carray_get(md->mdir_msg_list, i);
258 271
259 if (msg_new) { 272 if (msg_new) {
260 delete = 0; 273 delete = 0;
261 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) 274 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
262 delete = 1; 275 delete = 1;
263 } 276 }
264 else { 277 else {
265 delete = 1; 278 delete = 1;
266 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) 279 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
267 delete = 0; 280 delete = 0;
268 } 281 }
269 282
270 if (delete) { 283 if (delete) {
271 chashdatum key; 284 chashdatum key;
272 285
273 key.data = msg->msg_uid; 286 key.data = msg->msg_uid;
274 key.len = strlen(msg->msg_uid); 287 key.len = strlen(msg->msg_uid);
275 chash_delete(md->mdir_msg_hash, &key, NULL); 288 chash_delete(md->mdir_msg_hash, &key, NULL);
276 289
277 carray_delete(md->mdir_msg_list, i); 290 carray_delete(md->mdir_msg_list, i);
278 msg_free(msg); 291 msg_free(msg);
279 } 292 }
280 else { 293 else {
281 i ++; 294 i ++;
282 } 295 }
283 } 296 }
284} 297}
285 298
286static int add_message(struct maildir * md, 299static int add_message(struct maildir * md,
287 char * filename, int is_new) 300 char * filename, int is_new)
288{ 301{
289 struct maildir_msg * msg; 302 struct maildir_msg * msg;
290 chashdatum key; 303 chashdatum key;
291 chashdatum value; 304 chashdatum value;
292 unsigned int i; 305 unsigned int i;
293 int res; 306 int res;
294 int r; 307 int r;
295 308
296 msg = msg_new(filename, is_new); 309 msg = msg_new(filename, is_new);
297 if (msg == NULL) { 310 if (msg == NULL) {
298 res = MAILDIR_ERROR_MEMORY; 311 res = MAILDIR_ERROR_MEMORY;
299 goto err; 312 goto err;
300 } 313 }
301 314
302 r = carray_add(md->mdir_msg_list, msg, &i); 315 r = carray_add(md->mdir_msg_list, msg, &i);
303 if (r < 0) { 316 if (r < 0) {
304 res = MAILDIR_ERROR_MEMORY; 317 res = MAILDIR_ERROR_MEMORY;
305 goto free_msg; 318 goto free_msg;
306 } 319 }
307 320
308 key.data = msg->msg_uid; 321 key.data = msg->msg_uid;
309 key.len = strlen(msg->msg_uid); 322 key.len = strlen(msg->msg_uid);
310 value.data = msg; 323 value.data = msg;
311 value.len = 0; 324 value.len = 0;
312 325
313 r = chash_set(md->mdir_msg_hash, &key, &value, NULL); 326 r = chash_set(md->mdir_msg_hash, &key, &value, NULL);
314 if (r < 0) { 327 if (r < 0) {
315 res = MAILDIR_ERROR_MEMORY; 328 res = MAILDIR_ERROR_MEMORY;
316 goto delete; 329 goto delete;
317 } 330 }
318 331
319 return MAILDIR_NO_ERROR; 332 return MAILDIR_NO_ERROR;
320 333
321 delete: 334 delete:
322 carray_delete(md->mdir_msg_list, i); 335 carray_delete(md->mdir_msg_list, i);
323 free_msg: 336 free_msg:
324 msg_free(msg); 337 msg_free(msg);
325 err: 338 err:
326 return res; 339 return res;
327} 340}
328 341
329static int add_directory(struct maildir * md, char * path, int is_new) 342static int add_directory(struct maildir * md, char * path, int is_new)
330{ 343{
331 DIR * d; 344 DIR * d;
332 struct dirent * entry; 345 struct dirent * entry;
333 int res; 346 int res;
334 int r; 347 int r;
335#if 0 348#if 0
336 char filename[PATH_MAX]; 349 char filename[PATH_MAX];
337#endif 350#endif
338 351
339 d = opendir(path); 352 d = opendir(path);
340 if (d == NULL) { 353 if (d == NULL) {
341 res = MAILDIR_ERROR_DIRECTORY; 354 res = MAILDIR_ERROR_DIRECTORY;
342 goto err; 355 goto err;
diff --git a/libetpan/src/low-level/mh/mailmh.c b/libetpan/src/low-level/mh/mailmh.c
index 42cab9d..f8c694d 100644
--- a/libetpan/src/low-level/mh/mailmh.c
+++ b/libetpan/src/low-level/mh/mailmh.c
@@ -731,259 +731,262 @@ int mailmh_folder_get_message_size(struct mailmh_folder * folder,
731 return MAILMH_NO_ERROR; 731 return MAILMH_NO_ERROR;
732} 732}
733 733
734int mailmh_folder_add_message_uid(struct mailmh_folder * folder, 734int mailmh_folder_add_message_uid(struct mailmh_folder * folder,
735 const char * message, size_t size, 735 const char * message, size_t size,
736 uint32_t * pindex) 736 uint32_t * pindex)
737{ 737{
738 char * tmpname; 738 char * tmpname;
739 int fd; 739 int fd;
740 size_t namesize; 740 size_t namesize;
741 size_t left; 741 size_t left;
742 ssize_t res; 742 ssize_t res;
743 struct mailmh_msg_info * msg_info; 743 struct mailmh_msg_info * msg_info;
744 uint32_t index; 744 uint32_t index;
745 int error; 745 int error;
746 int r; 746 int r;
747 unsigned int array_index; 747 unsigned int array_index;
748 struct stat buf; 748 struct stat buf;
749 chashdatum key; 749 chashdatum key;
750 chashdatum data; 750 chashdatum data;
751 751
752#if 0 752#if 0
753 r = mailmh_folder_update(folder); 753 r = mailmh_folder_update(folder);
754 if (r != MAILMH_NO_ERROR) { 754 if (r != MAILMH_NO_ERROR) {
755 error = r; 755 error = r;
756 goto err; 756 goto err;
757 } 757 }
758#endif 758#endif
759 759
760 namesize = strlen(folder->fl_filename) + 20; 760 namesize = strlen(folder->fl_filename) + 20;
761 tmpname = malloc(namesize); 761 tmpname = malloc(namesize);
762 snprintf(tmpname, namesize, "%s%ctmpXXXXXX", 762 snprintf(tmpname, namesize, "%s%ctmpXXXXXX",
763 folder->fl_filename, MAIL_DIR_SEPARATOR); 763 folder->fl_filename, MAIL_DIR_SEPARATOR);
764 fd = mkstemp(tmpname); 764 fd = mkstemp(tmpname);
765 if (fd < 0) { 765 if (fd < 0) {
766 error = MAILMH_ERROR_FILE; 766 error = MAILMH_ERROR_FILE;
767 goto free; 767 goto free;
768 } 768 }
769 769
770 left = size; 770 left = size;
771 while (left > 0) { 771 while (left > 0) {
772 res = write(fd, message, left); 772 res = write(fd, message, left);
773 if (res == -1) { 773 if (res == -1) {
774 close(fd); 774 close(fd);
775 error = MAILMH_ERROR_FILE; 775 error = MAILMH_ERROR_FILE;
776 goto free; 776 goto free;
777 } 777 }
778 778
779 left -= res; 779 left -= res;
780 } 780 }
781 close(fd); 781 close(fd);
782 782
783 r = stat(tmpname, &buf); 783 r = stat(tmpname, &buf);
784 if (r < 0) { 784 if (r < 0) {
785 error = MAILMH_ERROR_FILE; 785 error = MAILMH_ERROR_FILE;
786 goto free; 786 goto free;
787 } 787 }
788 788
789 r = mailmh_folder_alloc_msg(folder, tmpname, &index); 789 r = mailmh_folder_alloc_msg(folder, tmpname, &index);
790 if (r != MAILMH_NO_ERROR) { 790 if (r != MAILMH_NO_ERROR) {
791 unlink(tmpname); 791 unlink(tmpname);
792 error = MAILMH_ERROR_COULD_NOT_ALLOC_MSG; 792 error = MAILMH_ERROR_COULD_NOT_ALLOC_MSG;
793 goto free; 793 goto free;
794 } 794 }
795 free(tmpname); 795 free(tmpname);
796 796
797 msg_info = mailmh_msg_info_new(index, size, buf.st_mtime); 797 msg_info = mailmh_msg_info_new(index, size, buf.st_mtime);
798 if (msg_info == NULL) { 798 if (msg_info == NULL) {
799 mailmh_folder_remove_message(folder, index); 799 mailmh_folder_remove_message(folder, index);
800 error = MAILMH_ERROR_MEMORY; 800 error = MAILMH_ERROR_MEMORY;
801 goto err; 801 goto err;
802 } 802 }
803 803
804 r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); 804 r = carray_add(folder->fl_msgs_tab, msg_info, &array_index);
805 if (r < 0) { 805 if (r < 0) {
806 mailmh_folder_remove_message(folder, index); 806 mailmh_folder_remove_message(folder, index);
807 mailmh_msg_info_free(msg_info); 807 mailmh_msg_info_free(msg_info);
808 error = MAILMH_ERROR_MEMORY; 808 error = MAILMH_ERROR_MEMORY;
809 goto err; 809 goto err;
810 } 810 }
811 msg_info->msg_array_index = array_index; 811 msg_info->msg_array_index = array_index;
812 812
813#if 0 813#if 0
814 r = cinthash_add(folder->fl_msgs_hash, index, msg_info); 814 r = cinthash_add(folder->fl_msgs_hash, index, msg_info);
815#endif 815#endif
816 key.data = &index; 816 key.data = &index;
817 key.len = sizeof(index); 817 key.len = sizeof(index);
818 data.data = msg_info; 818 data.data = msg_info;
819 data.len = 0; 819 data.len = 0;
820 820
821 if (pindex != NULL) 821 if (pindex != NULL)
822 * pindex = index; 822 * pindex = index;
823 823
824 r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); 824 r = chash_set(folder->fl_msgs_hash, &key, &data, NULL);
825 if (r < 0) { 825 if (r < 0) {
826 carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); 826 carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index);
827 mailmh_msg_info_free(msg_info); 827 mailmh_msg_info_free(msg_info);
828 error = MAILMH_ERROR_MEMORY; 828 error = MAILMH_ERROR_MEMORY;
829 goto err; 829 goto err;
830 } 830 }
831 831
832 return MAILMH_NO_ERROR; 832 return MAILMH_NO_ERROR;
833 833
834 free: 834 free:
835 free(tmpname); 835 free(tmpname);
836 err: 836 err:
837 return error; 837 return error;
838} 838}
839 839
840int mailmh_folder_add_message(struct mailmh_folder * folder, 840int mailmh_folder_add_message(struct mailmh_folder * folder,
841 const char * message, size_t size) 841 const char * message, size_t size)
842{ 842{
843 return mailmh_folder_add_message_uid(folder, message, size, NULL); 843 return mailmh_folder_add_message_uid(folder, message, size, NULL);
844} 844}
845 845
846int mailmh_folder_add_message_file_uid(struct mailmh_folder * folder, 846int mailmh_folder_add_message_file_uid(struct mailmh_folder * folder,
847 int fd, uint32_t * pindex) 847 int fd, uint32_t * pindex)
848{ 848{
849 char * message; 849 char * message;
850 struct stat buf; 850 struct stat buf;
851 int r; 851 int r;
852 852
853#if 0 853#if 0
854 r = mailmh_folder_update(folder); 854 r = mailmh_folder_update(folder);
855 if (r != MAILMH_NO_ERROR) 855 if (r != MAILMH_NO_ERROR)
856 return r; 856 return r;
857#endif 857#endif
858 858
859 if (fstat(fd, &buf) == -1) 859 if (fstat(fd, &buf) == -1)
860 return MAILMH_ERROR_FILE; 860 return MAILMH_ERROR_FILE;
861 861
862 message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 862 message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
863 if (message == MAP_FAILED) 863 if (message == MAP_FAILED)
864 return MAILMH_ERROR_FILE; 864 return MAILMH_ERROR_FILE;
865 865
866 r = mailmh_folder_add_message_uid(folder, message, buf.st_size, pindex); 866 r = mailmh_folder_add_message_uid(folder, message, buf.st_size, pindex);
867 867
868 munmap(message, buf.st_size); 868 munmap(message, buf.st_size);
869 869
870 return r; 870 return r;
871} 871}
872 872
873int mailmh_folder_add_message_file(struct mailmh_folder * folder, 873int mailmh_folder_add_message_file(struct mailmh_folder * folder,
874 int fd) 874 int fd)
875{ 875{
876 return mailmh_folder_add_message_file_uid(folder, fd, NULL); 876 return mailmh_folder_add_message_file_uid(folder, fd, NULL);
877} 877}
878 878
879int mailmh_folder_remove_message(struct mailmh_folder * folder, 879int mailmh_folder_remove_message(struct mailmh_folder * folder,
880 uint32_t index) 880 uint32_t index)
881{ 881{
882 char * filename; 882 char * filename;
883 struct mailmh_msg_info * msg_info; 883 struct mailmh_msg_info * msg_info;
884 int res; 884 int res;
885 int r; 885 int r;
886 chashdatum key; 886 chashdatum key;
887 chashdatum data; 887 chashdatum data;
888 888
889#if 0 889#if 0
890 r = mailmh_folder_update(folder); 890 r = mailmh_folder_update(folder);
891 if (r != MAILMH_NO_ERROR) { 891 if (r != MAILMH_NO_ERROR) {
892 res = r; 892 res = r;
893 goto err; 893 goto err;
894 } 894 }
895#endif 895#endif
896 896
897 r = mailmh_folder_get_message_filename(folder, index, &filename); 897 r = mailmh_folder_get_message_filename(folder, index, &filename);
898 if (filename == NULL) { 898 if (filename == NULL) {
899 res = r; 899 res = r;
900 goto err; 900 goto err;
901 } 901 }
902 902
903 if (unlink(filename) == -1) { 903 if (unlink(filename) == -1) {
904 res = MAILMH_ERROR_FILE; 904 res = MAILMH_ERROR_FILE;
905 goto free; 905 goto free;
906 } 906 }
907 907
908 key.data = &index; 908 key.data = &index;
909 key.len = sizeof(index); 909 key.len = sizeof(index);
910 r = chash_get(folder->fl_msgs_hash, &key, &data); 910 r = chash_get(folder->fl_msgs_hash, &key, &data);
911#if 0 911#if 0
912 msg_info = cinthash_find(folder->fl_msgs_hash, index); 912 msg_info = cinthash_find(folder->fl_msgs_hash, index);
913#endif 913#endif
914 if (r == 0) { 914 if (r == 0) {
915 msg_info = data.data; 915 msg_info = data.data;
916 916
917 carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); 917 carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index);
918#if 0 918#if 0
919 cinthash_remove(folder->fl_msgs_hash, index); 919 cinthash_remove(folder->fl_msgs_hash, index);
920#endif 920#endif
921 chash_delete(folder->fl_msgs_hash, &key, NULL); 921 chash_delete(folder->fl_msgs_hash, &key, NULL);
922 } 922 }
923 // LR memory leak fixed
924 mailmh_msg_info_free( msg_info );
925 free(filename);
923 926
924 return MAILMH_NO_ERROR; 927 return MAILMH_NO_ERROR;
925 928
926 free: 929 free:
927 free(filename); 930 free(filename);
928 err: 931 err:
929 return res; 932 return res;
930} 933}
931 934
932 935
933int mailmh_folder_move_message(struct mailmh_folder * dest_folder, 936int mailmh_folder_move_message(struct mailmh_folder * dest_folder,
934 struct mailmh_folder * src_folder, 937 struct mailmh_folder * src_folder,
935 uint32_t index) 938 uint32_t index)
936{ 939{
937 int fd; 940 int fd;
938 char * filename; 941 char * filename;
939 int r; 942 int r;
940 943
941#if 0 944#if 0
942 r = mailmh_folder_update(dest_folder); 945 r = mailmh_folder_update(dest_folder);
943 if (r != MAILMH_NO_ERROR) 946 if (r != MAILMH_NO_ERROR)
944 return r; 947 return r;
945 r = mailmh_folder_update(src_folder); 948 r = mailmh_folder_update(src_folder);
946 if (r != MAILMH_NO_ERROR) 949 if (r != MAILMH_NO_ERROR)
947 return r; 950 return r;
948#endif 951#endif
949 952
950 /* move on the same filesystem */ 953 /* move on the same filesystem */
951 r = mailmh_folder_get_message_filename(src_folder, index, &filename); 954 r = mailmh_folder_get_message_filename(src_folder, index, &filename);
952 if (r != MAILMH_NO_ERROR) 955 if (r != MAILMH_NO_ERROR)
953 return r; 956 return r;
954 957
955 r = mailmh_folder_alloc_msg(dest_folder, filename, &index); 958 r = mailmh_folder_alloc_msg(dest_folder, filename, &index);
956 free(filename); 959 free(filename);
957 if (r == MAILMH_NO_ERROR) 960 if (r == MAILMH_NO_ERROR)
958 return MAILMH_NO_ERROR; 961 return MAILMH_NO_ERROR;
959 962
960 /* move on the different filesystems */ 963 /* move on the different filesystems */
961 r = mailmh_folder_get_message_fd(src_folder, index, O_RDONLY, &fd); 964 r = mailmh_folder_get_message_fd(src_folder, index, O_RDONLY, &fd);
962 if (r != MAILMH_NO_ERROR) 965 if (r != MAILMH_NO_ERROR)
963 return r; 966 return r;
964 967
965 r = mailmh_folder_add_message_file(dest_folder, fd); 968 r = mailmh_folder_add_message_file(dest_folder, fd);
966 if (r != MAILMH_NO_ERROR) { 969 if (r != MAILMH_NO_ERROR) {
967 close(fd); 970 close(fd);
968 return r; 971 return r;
969 } 972 }
970 973
971 close(fd); 974 close(fd);
972 975
973 r = mailmh_folder_remove_message(src_folder, index); 976 r = mailmh_folder_remove_message(src_folder, index);
974 977
975 return MAILMH_NO_ERROR; 978 return MAILMH_NO_ERROR;
976} 979}
977 980
978unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder) 981unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder)
979{ 982{
980 unsigned int i; 983 unsigned int i;
981 unsigned int count; 984 unsigned int count;
982 985
983 count = 0; 986 count = 0;
984 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) 987 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++)
985 if (carray_get(folder->fl_msgs_tab, i) != NULL) 988 if (carray_get(folder->fl_msgs_tab, i) != NULL)
986 count ++; 989 count ++;
987 990
988 return count; 991 return count;
989} 992}
diff --git a/libetpan/src/low-level/pop3/mailpop3.c b/libetpan/src/low-level/pop3/mailpop3.c
index 6f77a3a..bca62d5 100644
--- a/libetpan/src/low-level/pop3/mailpop3.c
+++ b/libetpan/src/low-level/pop3/mailpop3.c
@@ -319,386 +319,389 @@ int mailpop3_connect(mailpop3 * f, mailstream * s)
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 return MAILPOP3_ERROR_BAD_PASSWORD; 512 // LR
513 fprintf(stderr,"POP3 login error. Response from server:\n%s\n",response );
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