-rw-r--r-- | libetpan/src/data-types/mailstream_helper.c | 11 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/pop3/pop3driver.c | 8 | ||||
-rw-r--r-- | libetpan/src/low-level/imap/mailimap_parser.c | 22 | ||||
-rw-r--r-- | libetpan/src/low-level/maildir/maildir.c | 17 | ||||
-rw-r--r-- | libetpan/src/low-level/mh/mailmh.c | 3 | ||||
-rw-r--r-- | libetpan/src/low-level/pop3/mailpop3.c | 7 |
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 | ||
41 | static void remove_trailing_eol(MMAPString * mmapstr) | 41 | static 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 | ||
53 | char * mailstream_read_line(mailstream * stream, MMAPString * line) | 53 | char * 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 | ||
61 | static char * mailstream_read_len_append(mailstream * stream, | 61 | static 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 | ||
75 | char * mailstream_read_line_append(mailstream * stream, MMAPString * line) | 75 | char * 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 | ||
110 | char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line) | 117 | char * 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 | ||
120 | int mailstream_is_end_multiline(const char * line) | 127 | int 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 |
130 | char * mailstream_read_multiline(mailstream * s, size_t size, | 137 | char * 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 | ||
179 | static gboolean end_of_multiline(const char * str, gint len) | 186 | static 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 | ||
211 | char * mailstream_read_multiline(mailstream * stream, size_t size, | 218 | char * 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 | ||
250 | static inline ssize_t send_data_line(mailstream * s, | 257 | static 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, | |||
60 | static int pop3driver_logout(mailsession * session); | 60 | static int pop3driver_logout(mailsession * session); |
61 | 61 | ||
62 | static int pop3driver_noop(mailsession * session); | 62 | static int pop3driver_noop(mailsession * session); |
63 | 63 | ||
64 | static int pop3driver_status_folder(mailsession * session, char * mb, | 64 | static 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 | ||
68 | static int pop3driver_messages_number(mailsession * session, char * mb, | 68 | static int pop3driver_messages_number(mailsession * session, char * mb, |
69 | uint32_t * result); | 69 | uint32_t * result); |
70 | 70 | ||
71 | static int pop3driver_remove_message(mailsession * session, uint32_t num); | 71 | static int pop3driver_remove_message(mailsession * session, uint32_t num); |
72 | 72 | ||
73 | static int pop3driver_get_messages_list(mailsession * session, | 73 | static int pop3driver_get_messages_list(mailsession * session, |
74 | struct mailmessage_list ** result); | 74 | struct mailmessage_list ** result); |
75 | 75 | ||
76 | static int pop3driver_get_message(mailsession * session, | 76 | static int pop3driver_get_message(mailsession * session, |
77 | uint32_t num, mailmessage ** result); | 77 | uint32_t num, mailmessage ** result); |
78 | 78 | ||
79 | static mailsession_driver local_pop3_session_driver = { | 79 | static 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 | ||
127 | mailsession_driver * pop3_session_driver = &local_pop3_session_driver; | 127 | mailsession_driver * pop3_session_driver = &local_pop3_session_driver; |
128 | 128 | ||
129 | static inline struct pop3_session_state_data * | 129 | static inline struct pop3_session_state_data * |
130 | get_data(mailsession * session) | 130 | get_data(mailsession * session) |
131 | { | 131 | { |
132 | return session->sess_data; | 132 | return session->sess_data; |
133 | } | 133 | } |
134 | 134 | ||
135 | static mailpop3 * get_pop3_session(mailsession * session) | 135 | static 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 | ||
140 | static int pop3driver_initialize(mailsession * session) | 140 | static 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 | ||
166 | static void pop3driver_uninitialize(mailsession * session) | 166 | static 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 | ||
178 | static int pop3driver_connect_stream(mailsession * session, mailstream * s) | 178 | static 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 | ||
193 | static int pop3driver_starttls(mailsession * session) | 193 | static 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 | ||
226 | static int pop3driver_parameters(mailsession * session, | 226 | static 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 | ||
248 | static int pop3driver_login(mailsession * session, | 248 | static 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 | ||
279 | static int pop3driver_logout(mailsession * session) | 285 | static 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 | ||
288 | static int pop3driver_noop(mailsession * session) | 294 | static 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 | ||
297 | static int pop3driver_status_folder(mailsession * session, char * mb, | 303 | static 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 | ||
316 | static int pop3driver_messages_number(mailsession * session, char * mb, | 322 | static 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 | ||
332 | static int pop3driver_remove_message(mailsession * session, uint32_t num) | 338 | static 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 | ||
358 | static int pop3driver_get_messages_list(mailsession * session, | 364 | static 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 | ||
369 | static int pop3driver_get_message(mailsession * session, | 375 | static 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 | ||
2232 | static int mailimap_body_fld_desc_parse(mailstream * fd, MMAPString * buffer, | 2232 | static 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 | ||
2245 | static int | 2245 | static int |
2246 | mailimap_body_fld_dsp_parse(mailstream * fd, MMAPString * buffer, | 2246 | mailimap_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 | ||
2333 | static inline int | 2333 | static inline int |
2334 | mailimap_body_fld_known_enc_parse(mailstream * fd, MMAPString * buffer, | 2334 | mailimap_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 | ||
2375 | static int | 2375 | static int |
2376 | mailimap_body_fld_enc_parse(mailstream * fd, MMAPString * buffer, | 2376 | mailimap_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 | ||
2433 | static int mailimap_body_fld_id_parse(mailstream * fd, MMAPString * buffer, | 2451 | static 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 | ||
2451 | static int | 2469 | static int |
2452 | mailimap_body_fld_lang_list_parse(mailstream * fd, MMAPString * buffer, | 2470 | mailimap_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 | ||
2519 | static int | 2537 | static int |
2520 | mailimap_body_fld_lang_parse(mailstream * fd, MMAPString * buffer, | 2538 | mailimap_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 | ||
2584 | static int mailimap_body_fld_lines_parse(mailstream * fd, | 2602 | static 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 | ||
2595 | static int mailimap_body_fld_md5_parse(mailstream * fd, MMAPString * buffer, | 2613 | static 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 | ||
58 | struct maildir * maildir_new(const char * path) | 58 | struct 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 | ||
93 | static void maildir_flush(struct maildir * md, int msg_new); | 93 | static void maildir_flush(struct maildir * md, int msg_new); |
94 | 94 | ||
95 | void maildir_free(struct maildir * md) | 95 | void 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 | ||
106 | static char * maildir_get_new_message_filename(struct maildir * md, | 106 | static 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 | ||
164 | static void msg_free(struct maildir_msg * msg) | 177 | static 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 | ||
177 | static struct maildir_msg * msg_new(char * filename, int new_msg) | 190 | static 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 | ||
248 | static void maildir_flush(struct maildir * md, int msg_new) | 261 | static 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 | ||
286 | static int add_message(struct maildir * md, | 299 | static 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 | ||
329 | static int add_directory(struct maildir * md, char * path, int is_new) | 342 | static 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 | ||
734 | int mailmh_folder_add_message_uid(struct mailmh_folder * folder, | 734 | int 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 | ||
840 | int mailmh_folder_add_message(struct mailmh_folder * folder, | 840 | int 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 | ||
846 | int mailmh_folder_add_message_file_uid(struct mailmh_folder * folder, | 846 | int 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 | ||
873 | int mailmh_folder_add_message_file(struct mailmh_folder * folder, | 873 | int 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 | ||
879 | int mailmh_folder_remove_message(struct mailmh_folder * folder, | 879 | int 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 | ||
933 | int mailmh_folder_move_message(struct mailmh_folder * dest_folder, | 936 | int 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 | ||
978 | unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder) | 981 | unsigned 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 | ||
334 | int mailpop3_quit(mailpop3 * f) | 334 | int 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 | ||
413 | int mailpop3_apop(mailpop3 * f, | 413 | int 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 | ||
463 | int mailpop3_user(mailpop3 * f, const char * user) | 463 | int 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 | ||
490 | int mailpop3_pass(mailpop3 * f, const char * password) | 490 | int 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 | ||
519 | static int read_list(mailpop3 * f, carray ** result); | 522 | static int read_list(mailpop3 * f, carray ** result); |
520 | 523 | ||
521 | 524 | ||
522 | 525 | ||
523 | static int read_uidl(mailpop3 * f, carray * msg_tab); | 526 | static int read_uidl(mailpop3 * f, carray * msg_tab); |
524 | 527 | ||
525 | 528 | ||
526 | 529 | ||
527 | static int mailpop3_do_uidl(mailpop3 * f, carray * msg_tab) | 530 | static 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 | ||
560 | static int mailpop3_do_list(mailpop3 * f) | 563 | static 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 | ||
604 | static void mailpop3_list_if_needed(mailpop3 * f) | 607 | static 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 | ||
614 | void mailpop3_list(mailpop3 * f, carray ** result) | 617 | void 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 | ||
620 | static inline struct mailpop3_msg_info * | 623 | static inline struct mailpop3_msg_info * |
621 | find_msg(mailpop3 * f, unsigned int index) | 624 | find_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 | ||
638 | static void mailpop3_multiline_response_free(char * str) | 641 | static void mailpop3_multiline_response_free(char * str) |
639 | { | 642 | { |
640 | mmap_string_unref(str); | 643 | mmap_string_unref(str); |
641 | } | 644 | } |
642 | 645 | ||
643 | void mailpop3_top_free(char * str) | 646 | void mailpop3_top_free(char * str) |
644 | { | 647 | { |
645 | mailpop3_multiline_response_free(str); | 648 | mailpop3_multiline_response_free(str); |
646 | } | 649 | } |
647 | 650 | ||
648 | void mailpop3_retr_free(char * str) | 651 | void 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 | ||
660 | static int | 663 | static int |
661 | mailpop3_get_content(mailpop3 * f, struct mailpop3_msg_info * msginfo, | 664 | mailpop3_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 | ||
698 | int mailpop3_retr(mailpop3 * f, unsigned int index, char ** result, | 701 | int 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 | ||