-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,515 +1,522 @@ | |||
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 --; |
295 | 302 | ||
296 | fix_eol = 1; | 303 | fix_eol = 1; |
297 | break; | 304 | break; |
298 | } | 305 | } |
299 | 306 | ||
300 | line ++; | 307 | line ++; |
301 | length --; | 308 | length --; |
302 | count ++; | 309 | count ++; |
303 | } | 310 | } |
304 | 311 | ||
305 | if (fix_eol) { | 312 | if (fix_eol) { |
306 | if (mailstream_write(s, start, count - 1) == -1) | 313 | if (mailstream_write(s, start, count - 1) == -1) |
307 | goto err; | 314 | goto err; |
308 | if (mailstream_write(s, "\r\n", 2) == -1) | 315 | if (mailstream_write(s, "\r\n", 2) == -1) |
309 | goto err; | 316 | goto err; |
310 | } | 317 | } |
311 | else { | 318 | else { |
312 | if (mailstream_write(s, start, count) == -1) | 319 | if (mailstream_write(s, start, count) == -1) |
313 | goto err; | 320 | goto err; |
314 | } | 321 | } |
315 | 322 | ||
316 | 323 | ||
317 | #if 0 | 324 | #if 0 |
318 | while (* line != '\n') { | 325 | while (* line != '\n') { |
319 | if (* line == '\r') | 326 | if (* line == '\r') |
320 | pos = line; | 327 | pos = line; |
321 | if (* line == '\0') | 328 | if (* line == '\0') |
322 | return line; | 329 | return line; |
323 | if (mailstream_write(s, line, 1) == -1) | 330 | if (mailstream_write(s, line, 1) == -1) |
324 | goto err; | 331 | goto err; |
325 | line ++; | 332 | line ++; |
326 | } | 333 | } |
327 | if (pos + 1 == line) { | 334 | if (pos + 1 == line) { |
328 | if (mailstream_write(s, line, 1) == -1) | 335 | if (mailstream_write(s, line, 1) == -1) |
329 | goto err; | 336 | goto err; |
330 | } | 337 | } |
331 | else { | 338 | else { |
332 | if (mailstream_write(s, "\r\n", 2) == -1) | 339 | if (mailstream_write(s, "\r\n", 2) == -1) |
333 | goto err; | 340 | goto err; |
334 | } | 341 | } |
335 | line ++; | 342 | line ++; |
336 | #endif | 343 | #endif |
337 | 344 | ||
338 | return count; | 345 | return count; |
339 | 346 | ||
340 | err: | 347 | err: |
341 | return -1; | 348 | return -1; |
342 | } | 349 | } |
343 | 350 | ||
344 | static inline int send_data_crlf(mailstream * s, const char * message, | 351 | static inline int send_data_crlf(mailstream * s, const char * message, |
345 | size_t size, | 352 | size_t size, |
346 | int quoted, | 353 | int quoted, |
347 | size_t progr_rate, | 354 | size_t progr_rate, |
348 | progress_function * progr_fun) | 355 | progress_function * progr_fun) |
349 | { | 356 | { |
350 | const char * current; | 357 | const char * current; |
351 | size_t count; | 358 | size_t count; |
352 | size_t last; | 359 | size_t last; |
353 | size_t remaining; | 360 | size_t remaining; |
354 | 361 | ||
355 | count = 0; | 362 | count = 0; |
356 | last = 0; | 363 | last = 0; |
357 | 364 | ||
358 | current = message; | 365 | current = message; |
359 | remaining = size; | 366 | remaining = size; |
360 | 367 | ||
361 | while (remaining > 0) { | 368 | while (remaining > 0) { |
362 | ssize_t length; | 369 | ssize_t length; |
363 | 370 | ||
364 | if (quoted) { | 371 | if (quoted) { |
365 | if (current[0] == '.') | 372 | if (current[0] == '.') |
366 | if (mailstream_write(s, ".", 1) == -1) | 373 | if (mailstream_write(s, ".", 1) == -1) |
367 | goto err; | 374 | goto err; |
368 | } | 375 | } |
369 | 376 | ||
370 | length = send_data_line(s, current, remaining); | 377 | length = send_data_line(s, current, remaining); |
371 | if (length < 0) | 378 | if (length < 0) |
372 | goto err; | 379 | goto err; |
373 | 380 | ||
374 | current += length; | 381 | current += length; |
375 | 382 | ||
376 | count += length; | 383 | count += length; |
377 | if ((progr_rate != 0) && (progr_fun != NULL)) | 384 | if ((progr_rate != 0) && (progr_fun != NULL)) |
378 | if (count - last >= progr_rate) { | 385 | if (count - last >= progr_rate) { |
379 | (* progr_fun)(count, size); | 386 | (* progr_fun)(count, size); |
380 | last = count; | 387 | last = count; |
381 | } | 388 | } |
382 | 389 | ||
383 | remaining -= length; | 390 | remaining -= length; |
384 | } | 391 | } |
385 | 392 | ||
386 | return 0; | 393 | return 0; |
387 | 394 | ||
388 | err: | 395 | err: |
389 | return -1; | 396 | return -1; |
390 | } | 397 | } |
391 | 398 | ||
392 | int mailstream_send_data_crlf(mailstream * s, const char * message, | 399 | int mailstream_send_data_crlf(mailstream * s, const char * message, |
393 | size_t size, | 400 | size_t size, |
394 | size_t progr_rate, | 401 | size_t progr_rate, |
395 | progress_function * progr_fun) | 402 | progress_function * progr_fun) |
396 | { | 403 | { |
397 | return send_data_crlf(s, message, size, 0, progr_rate, progr_fun); | 404 | return send_data_crlf(s, message, size, 0, progr_rate, progr_fun); |
398 | } | 405 | } |
399 | 406 | ||
400 | int mailstream_send_data(mailstream * s, const char * message, | 407 | int mailstream_send_data(mailstream * s, const char * message, |
401 | size_t size, | 408 | size_t size, |
402 | size_t progr_rate, | 409 | size_t progr_rate, |
403 | progress_function * progr_fun) | 410 | progress_function * progr_fun) |
404 | { | 411 | { |
405 | if (send_data_crlf(s, message, size, 1, progr_rate, progr_fun) == -1) | 412 | if (send_data_crlf(s, message, size, 1, progr_rate, progr_fun) == -1) |
406 | goto err; | 413 | goto err; |
407 | 414 | ||
408 | if (mailstream_write(s, "\r\n.\r\n", 5) == -1) | 415 | if (mailstream_write(s, "\r\n.\r\n", 5) == -1) |
409 | goto err; | 416 | goto err; |
410 | 417 | ||
411 | if (mailstream_flush(s) == -1) | 418 | if (mailstream_flush(s) == -1) |
412 | goto err; | 419 | goto err; |
413 | 420 | ||
414 | return 0; | 421 | return 0; |
415 | 422 | ||
416 | err: | 423 | err: |
417 | return -1; | 424 | return -1; |
418 | } | 425 | } |
419 | 426 | ||
420 | static inline ssize_t get_data_size(const char * line, size_t length, | 427 | static inline ssize_t get_data_size(const char * line, size_t length, |
421 | size_t * result) | 428 | size_t * result) |
422 | { | 429 | { |
423 | int fix_eol; | 430 | int fix_eol; |
424 | const char * start; | 431 | const char * start; |
425 | size_t count; | 432 | size_t count; |
426 | size_t fixed_count; | 433 | size_t fixed_count; |
427 | 434 | ||
428 | start = line; | 435 | start = line; |
429 | 436 | ||
430 | fix_eol = 0; | 437 | fix_eol = 0; |
431 | count = 0; | 438 | count = 0; |
432 | fixed_count = 0; | 439 | fixed_count = 0; |
433 | 440 | ||
434 | while (1) { | 441 | while (1) { |
435 | if (length == 0) | 442 | if (length == 0) |
436 | break; | 443 | break; |
437 | 444 | ||
438 | if (* line == '\r') { | 445 | if (* line == '\r') { |
439 | line ++; | 446 | line ++; |
440 | 447 | ||
441 | count ++; | 448 | count ++; |
442 | length --; | 449 | length --; |
443 | 450 | ||
444 | if (length == 0) { | 451 | if (length == 0) { |
445 | fix_eol = 1; | 452 | fix_eol = 1; |
446 | fixed_count ++; | 453 | fixed_count ++; |
447 | break; | 454 | break; |
448 | } | 455 | } |
449 | 456 | ||
450 | if (* line == '\n') { | 457 | if (* line == '\n') { |
451 | line ++; | 458 | line ++; |
452 | 459 | ||
453 | count ++; | 460 | count ++; |
454 | length --; | 461 | length --; |
455 | 462 | ||
456 | break; | 463 | break; |
457 | } | 464 | } |
458 | else { | 465 | else { |
459 | fix_eol = 1; | 466 | fix_eol = 1; |
460 | fixed_count ++; | 467 | fixed_count ++; |
461 | break; | 468 | break; |
462 | } | 469 | } |
463 | } | 470 | } |
464 | else if (* line == '\n') { | 471 | else if (* line == '\n') { |
465 | line ++; | 472 | line ++; |
466 | 473 | ||
467 | count ++; | 474 | count ++; |
468 | length --; | 475 | length --; |
469 | 476 | ||
470 | fix_eol = 1; | 477 | fix_eol = 1; |
471 | fixed_count ++; | 478 | fixed_count ++; |
472 | break; | 479 | break; |
473 | } | 480 | } |
474 | 481 | ||
475 | line ++; | 482 | line ++; |
476 | length --; | 483 | length --; |
477 | count ++; | 484 | count ++; |
478 | } | 485 | } |
479 | 486 | ||
480 | * result = count + fixed_count; | 487 | * result = count + fixed_count; |
481 | 488 | ||
482 | return count; | 489 | return count; |
483 | } | 490 | } |
484 | 491 | ||
485 | size_t mailstream_get_data_crlf_size(const char * message, size_t size) | 492 | size_t mailstream_get_data_crlf_size(const char * message, size_t size) |
486 | { | 493 | { |
487 | const char * current; | 494 | const char * current; |
488 | size_t count; | 495 | size_t count; |
489 | size_t last; | 496 | size_t last; |
490 | size_t remaining; | 497 | size_t remaining; |
491 | size_t fixed_count; | 498 | size_t fixed_count; |
492 | 499 | ||
493 | count = 0; | 500 | count = 0; |
494 | last = 0; | 501 | last = 0; |
495 | fixed_count = 0; | 502 | fixed_count = 0; |
496 | 503 | ||
497 | current = message; | 504 | current = message; |
498 | remaining = size; | 505 | remaining = size; |
499 | 506 | ||
500 | while (remaining > 0) { | 507 | while (remaining > 0) { |
501 | ssize_t length; | 508 | ssize_t length; |
502 | size_t line_count; | 509 | size_t line_count; |
503 | 510 | ||
504 | length = get_data_size(current, remaining, &line_count); | 511 | length = get_data_size(current, remaining, &line_count); |
505 | 512 | ||
506 | fixed_count += line_count; | 513 | fixed_count += line_count; |
507 | current += length; | 514 | current += length; |
508 | 515 | ||
509 | count += length; | 516 | count += length; |
510 | 517 | ||
511 | remaining -= length; | 518 | remaining -= length; |
512 | } | 519 | } |
513 | 520 | ||
514 | return fixed_count; | 521 | return fixed_count; |
515 | } | 522 | } |
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 | |||
@@ -1,388 +1,394 @@ | |||
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 "pop3driver.h" | 36 | #include "pop3driver.h" |
37 | 37 | ||
38 | #include <string.h> | 38 | #include <string.h> |
39 | #include <stdlib.h> | 39 | #include <stdlib.h> |
40 | 40 | ||
41 | #include "pop3driver_message.h" | 41 | #include "pop3driver_message.h" |
42 | #include "maildriver_tools.h" | 42 | #include "maildriver_tools.h" |
43 | #include "pop3driver_tools.h" | 43 | #include "pop3driver_tools.h" |
44 | #include "mailmessage.h" | 44 | #include "mailmessage.h" |
45 | 45 | ||
46 | static int pop3driver_initialize(mailsession * session); | 46 | static int pop3driver_initialize(mailsession * session); |
47 | 47 | ||
48 | static void pop3driver_uninitialize(mailsession * session); | 48 | static void pop3driver_uninitialize(mailsession * session); |
49 | 49 | ||
50 | static int pop3driver_parameters(mailsession * session, | 50 | static int pop3driver_parameters(mailsession * session, |
51 | int id, void * value); | 51 | int id, void * value); |
52 | 52 | ||
53 | static int pop3driver_connect_stream(mailsession * session, mailstream * s); | 53 | static int pop3driver_connect_stream(mailsession * session, mailstream * s); |
54 | 54 | ||
55 | static int pop3driver_starttls(mailsession * session); | 55 | static int pop3driver_starttls(mailsession * session); |
56 | 56 | ||
57 | static int pop3driver_login(mailsession * session, | 57 | static int pop3driver_login(mailsession * session, |
58 | char * userid, char * password); | 58 | char * userid, char * password); |
59 | 59 | ||
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 | |||
@@ -1634,1538 +1634,1556 @@ static int mailimap_body_parse(mailstream * fd, MMAPString * buffer, | |||
1634 | r = mailimap_body_type_1part_parse(fd, buffer, &cur_token, &body_type_1part, | 1634 | r = mailimap_body_type_1part_parse(fd, buffer, &cur_token, &body_type_1part, |
1635 | progr_rate, progr_fun); | 1635 | progr_rate, progr_fun); |
1636 | if (r == MAILIMAP_NO_ERROR) | 1636 | if (r == MAILIMAP_NO_ERROR) |
1637 | type = MAILIMAP_BODY_1PART; | 1637 | type = MAILIMAP_BODY_1PART; |
1638 | 1638 | ||
1639 | if (r == MAILIMAP_ERROR_PARSE) { | 1639 | if (r == MAILIMAP_ERROR_PARSE) { |
1640 | r = mailimap_body_type_mpart_parse(fd, buffer, &cur_token, | 1640 | r = mailimap_body_type_mpart_parse(fd, buffer, &cur_token, |
1641 | &body_type_mpart, | 1641 | &body_type_mpart, |
1642 | progr_rate, progr_fun); | 1642 | progr_rate, progr_fun); |
1643 | 1643 | ||
1644 | if (r == MAILIMAP_NO_ERROR) | 1644 | if (r == MAILIMAP_NO_ERROR) |
1645 | type = MAILIMAP_BODY_MPART; | 1645 | type = MAILIMAP_BODY_MPART; |
1646 | } | 1646 | } |
1647 | 1647 | ||
1648 | if (r != MAILIMAP_NO_ERROR) { | 1648 | if (r != MAILIMAP_NO_ERROR) { |
1649 | res = r; | 1649 | res = r; |
1650 | goto err; | 1650 | goto err; |
1651 | } | 1651 | } |
1652 | 1652 | ||
1653 | r = mailimap_cparenth_parse(fd, buffer, &cur_token); | 1653 | r = mailimap_cparenth_parse(fd, buffer, &cur_token); |
1654 | if (r != MAILIMAP_NO_ERROR) { | 1654 | if (r != MAILIMAP_NO_ERROR) { |
1655 | res = r; | 1655 | res = r; |
1656 | goto free; | 1656 | goto free; |
1657 | } | 1657 | } |
1658 | 1658 | ||
1659 | body = mailimap_body_new(type, body_type_1part, body_type_mpart); | 1659 | body = mailimap_body_new(type, body_type_1part, body_type_mpart); |
1660 | if (body == NULL) { | 1660 | if (body == NULL) { |
1661 | res = MAILIMAP_ERROR_MEMORY; | 1661 | res = MAILIMAP_ERROR_MEMORY; |
1662 | goto free; | 1662 | goto free; |
1663 | } | 1663 | } |
1664 | 1664 | ||
1665 | * result = body; | 1665 | * result = body; |
1666 | * index = cur_token; | 1666 | * index = cur_token; |
1667 | 1667 | ||
1668 | return MAILIMAP_NO_ERROR; | 1668 | return MAILIMAP_NO_ERROR; |
1669 | 1669 | ||
1670 | free: | 1670 | free: |
1671 | if (body_type_1part) | 1671 | if (body_type_1part) |
1672 | mailimap_body_type_1part_free(body_type_1part); | 1672 | mailimap_body_type_1part_free(body_type_1part); |
1673 | if (body_type_mpart) | 1673 | if (body_type_mpart) |
1674 | mailimap_body_type_mpart_free(body_type_mpart); | 1674 | mailimap_body_type_mpart_free(body_type_mpart); |
1675 | err: | 1675 | err: |
1676 | return res; | 1676 | return res; |
1677 | } | 1677 | } |
1678 | 1678 | ||
1679 | /* | 1679 | /* |
1680 | body-extension = nstring / number / | 1680 | body-extension = nstring / number / |
1681 | "(" body-extension *(SP body-extension) ")" | 1681 | "(" body-extension *(SP body-extension) ")" |
1682 | ; Future expansion. Client implementations | 1682 | ; Future expansion. Client implementations |
1683 | ; MUST accept body-extension fields. Server | 1683 | ; MUST accept body-extension fields. Server |
1684 | ; implementations MUST NOT generate | 1684 | ; implementations MUST NOT generate |
1685 | ; body-extension fields except as defined by | 1685 | ; body-extension fields except as defined by |
1686 | ; future standard or standards-track | 1686 | ; future standard or standards-track |
1687 | ; revisions of this specification. | 1687 | ; revisions of this specification. |
1688 | */ | 1688 | */ |
1689 | 1689 | ||
1690 | /* | 1690 | /* |
1691 | "(" body-extension *(SP body-extension) ")" | 1691 | "(" body-extension *(SP body-extension) ")" |
1692 | */ | 1692 | */ |
1693 | 1693 | ||
1694 | static int | 1694 | static int |
1695 | mailimap_body_ext_list_parse(mailstream * fd, MMAPString * buffer, | 1695 | mailimap_body_ext_list_parse(mailstream * fd, MMAPString * buffer, |
1696 | size_t * index, | 1696 | size_t * index, |
1697 | clist ** result, | 1697 | clist ** result, |
1698 | size_t progr_rate, | 1698 | size_t progr_rate, |
1699 | progress_function * progr_fun) | 1699 | progress_function * progr_fun) |
1700 | { | 1700 | { |
1701 | size_t cur_token; | 1701 | size_t cur_token; |
1702 | clist * list; | 1702 | clist * list; |
1703 | int r; | 1703 | int r; |
1704 | int res; | 1704 | int res; |
1705 | 1705 | ||
1706 | cur_token = * index; | 1706 | cur_token = * index; |
1707 | 1707 | ||
1708 | r = mailimap_oparenth_parse(fd, buffer, &cur_token); | 1708 | r = mailimap_oparenth_parse(fd, buffer, &cur_token); |
1709 | if (r != MAILIMAP_NO_ERROR) { | 1709 | if (r != MAILIMAP_NO_ERROR) { |
1710 | res = r; | 1710 | res = r; |
1711 | goto err; | 1711 | goto err; |
1712 | } | 1712 | } |
1713 | 1713 | ||
1714 | r = mailimap_struct_spaced_list_parse(fd, buffer, | 1714 | r = mailimap_struct_spaced_list_parse(fd, buffer, |
1715 | &cur_token, &list, | 1715 | &cur_token, &list, |
1716 | (mailimap_struct_parser * ) | 1716 | (mailimap_struct_parser * ) |
1717 | mailimap_body_extension_parse, | 1717 | mailimap_body_extension_parse, |
1718 | (mailimap_struct_destructor * ) | 1718 | (mailimap_struct_destructor * ) |
1719 | mailimap_body_extension_free, | 1719 | mailimap_body_extension_free, |
1720 | progr_rate, progr_fun); | 1720 | progr_rate, progr_fun); |
1721 | if (r != MAILIMAP_NO_ERROR) { | 1721 | if (r != MAILIMAP_NO_ERROR) { |
1722 | res = r; | 1722 | res = r; |
1723 | goto err; | 1723 | goto err; |
1724 | } | 1724 | } |
1725 | 1725 | ||
1726 | r = mailimap_cparenth_parse(fd, buffer, &cur_token); | 1726 | r = mailimap_cparenth_parse(fd, buffer, &cur_token); |
1727 | if (r != MAILIMAP_NO_ERROR) { | 1727 | if (r != MAILIMAP_NO_ERROR) { |
1728 | res = r; | 1728 | res = r; |
1729 | goto free_list; | 1729 | goto free_list; |
1730 | } | 1730 | } |
1731 | 1731 | ||
1732 | * index = cur_token; | 1732 | * index = cur_token; |
1733 | * result = list; | 1733 | * result = list; |
1734 | 1734 | ||
1735 | return MAILIMAP_NO_ERROR; | 1735 | return MAILIMAP_NO_ERROR; |
1736 | 1736 | ||
1737 | free_list: | 1737 | free_list: |
1738 | clist_foreach(list, (clist_func) mailimap_body_extension_free, NULL); | 1738 | clist_foreach(list, (clist_func) mailimap_body_extension_free, NULL); |
1739 | clist_free(list); | 1739 | clist_free(list); |
1740 | err: | 1740 | err: |
1741 | return res; | 1741 | return res; |
1742 | } | 1742 | } |
1743 | 1743 | ||
1744 | /* | 1744 | /* |
1745 | body-extension = nstring / number / | 1745 | body-extension = nstring / number / |
1746 | "(" body-extension *(SP body-extension) ")" | 1746 | "(" body-extension *(SP body-extension) ")" |
1747 | ; Future expansion. Client implementations | 1747 | ; Future expansion. Client implementations |
1748 | ; MUST accept body-extension fields. Server | 1748 | ; MUST accept body-extension fields. Server |
1749 | ; implementations MUST NOT generate | 1749 | ; implementations MUST NOT generate |
1750 | ; body-extension fields except as defined by | 1750 | ; body-extension fields except as defined by |
1751 | ; future standard or standards-track | 1751 | ; future standard or standards-track |
1752 | ; revisions of this specification. | 1752 | ; revisions of this specification. |
1753 | */ | 1753 | */ |
1754 | 1754 | ||
1755 | static int | 1755 | static int |
1756 | mailimap_body_extension_parse(mailstream * fd, MMAPString * buffer, | 1756 | mailimap_body_extension_parse(mailstream * fd, MMAPString * buffer, |
1757 | size_t * index, | 1757 | size_t * index, |
1758 | struct mailimap_body_extension ** result, | 1758 | struct mailimap_body_extension ** result, |
1759 | size_t progr_rate, | 1759 | size_t progr_rate, |
1760 | progress_function * progr_fun) | 1760 | progress_function * progr_fun) |
1761 | { | 1761 | { |
1762 | size_t cur_token; | 1762 | size_t cur_token; |
1763 | uint32_t number; | 1763 | uint32_t number; |
1764 | char * nstring; | 1764 | char * nstring; |
1765 | clist * body_extension_list; | 1765 | clist * body_extension_list; |
1766 | struct mailimap_body_extension * body_extension; | 1766 | struct mailimap_body_extension * body_extension; |
1767 | int type; | 1767 | int type; |
1768 | int r; | 1768 | int r; |
1769 | int res; | 1769 | int res; |
1770 | 1770 | ||
1771 | cur_token = * index; | 1771 | cur_token = * index; |
1772 | 1772 | ||
1773 | nstring = NULL; | 1773 | nstring = NULL; |
1774 | number = 0; | 1774 | number = 0; |
1775 | body_extension_list = NULL; | 1775 | body_extension_list = NULL; |
1776 | type = MAILIMAP_BODY_EXTENSION_ERROR; /* XXX - removes a gcc warning */ | 1776 | type = MAILIMAP_BODY_EXTENSION_ERROR; /* XXX - removes a gcc warning */ |
1777 | 1777 | ||
1778 | r = mailimap_nstring_parse(fd, buffer, &cur_token, &nstring, NULL, | 1778 | r = mailimap_nstring_parse(fd, buffer, &cur_token, &nstring, NULL, |
1779 | progr_rate, progr_fun); | 1779 | progr_rate, progr_fun); |
1780 | if (r == MAILIMAP_NO_ERROR) | 1780 | if (r == MAILIMAP_NO_ERROR) |
1781 | type = MAILIMAP_BODY_EXTENSION_NSTRING; | 1781 | type = MAILIMAP_BODY_EXTENSION_NSTRING; |
1782 | 1782 | ||
1783 | if (r == MAILIMAP_ERROR_PARSE) { | 1783 | if (r == MAILIMAP_ERROR_PARSE) { |
1784 | r = mailimap_number_parse(fd, buffer, &cur_token, &number); | 1784 | r = mailimap_number_parse(fd, buffer, &cur_token, &number); |
1785 | 1785 | ||
1786 | if (r == MAILIMAP_NO_ERROR) | 1786 | if (r == MAILIMAP_NO_ERROR) |
1787 | type = MAILIMAP_BODY_EXTENSION_NUMBER; | 1787 | type = MAILIMAP_BODY_EXTENSION_NUMBER; |
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | if (r == MAILIMAP_ERROR_PARSE) { | 1790 | if (r == MAILIMAP_ERROR_PARSE) { |
1791 | r = mailimap_body_ext_list_parse(fd, buffer, &cur_token, | 1791 | r = mailimap_body_ext_list_parse(fd, buffer, &cur_token, |
1792 | &body_extension_list, | 1792 | &body_extension_list, |
1793 | progr_rate, progr_fun); | 1793 | progr_rate, progr_fun); |
1794 | 1794 | ||
1795 | if (r == MAILIMAP_NO_ERROR) | 1795 | if (r == MAILIMAP_NO_ERROR) |
1796 | type = MAILIMAP_BODY_EXTENSION_LIST; | 1796 | type = MAILIMAP_BODY_EXTENSION_LIST; |
1797 | } | 1797 | } |
1798 | 1798 | ||
1799 | if (r != MAILIMAP_NO_ERROR) { | 1799 | if (r != MAILIMAP_NO_ERROR) { |
1800 | res = r; | 1800 | res = r; |
1801 | goto err; | 1801 | goto err; |
1802 | } | 1802 | } |
1803 | 1803 | ||
1804 | body_extension = mailimap_body_extension_new(type, nstring, number, | 1804 | body_extension = mailimap_body_extension_new(type, nstring, number, |
1805 | body_extension_list); | 1805 | body_extension_list); |
1806 | 1806 | ||
1807 | if (body_extension == NULL) { | 1807 | if (body_extension == NULL) { |
1808 | res = MAILIMAP_ERROR_MEMORY; | 1808 | res = MAILIMAP_ERROR_MEMORY; |
1809 | goto free; | 1809 | goto free; |
1810 | } | 1810 | } |
1811 | 1811 | ||
1812 | * result = body_extension; | 1812 | * result = body_extension; |
1813 | * index = cur_token; | 1813 | * index = cur_token; |
1814 | 1814 | ||
1815 | return MAILIMAP_NO_ERROR; | 1815 | return MAILIMAP_NO_ERROR; |
1816 | 1816 | ||
1817 | free: | 1817 | free: |
1818 | if (nstring != NULL) | 1818 | if (nstring != NULL) |
1819 | mailimap_nstring_free(nstring); | 1819 | mailimap_nstring_free(nstring); |
1820 | if (body_extension_list) { | 1820 | if (body_extension_list) { |
1821 | clist_foreach(body_extension_list, | 1821 | clist_foreach(body_extension_list, |
1822 | (clist_func) mailimap_body_extension_free, | 1822 | (clist_func) mailimap_body_extension_free, |
1823 | NULL); | 1823 | NULL); |
1824 | clist_free(body_extension_list); | 1824 | clist_free(body_extension_list); |
1825 | } | 1825 | } |
1826 | err: | 1826 | err: |
1827 | return res; | 1827 | return res; |
1828 | } | 1828 | } |
1829 | 1829 | ||
1830 | /* | 1830 | /* |
1831 | body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang | 1831 | body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang |
1832 | *(SP body-extension)]] | 1832 | *(SP body-extension)]] |
1833 | ; MUST NOT be returned on non-extensible | 1833 | ; MUST NOT be returned on non-extensible |
1834 | ; "BODY" fetch | 1834 | ; "BODY" fetch |
1835 | */ | 1835 | */ |
1836 | 1836 | ||
1837 | /* | 1837 | /* |
1838 | *(SP body-extension) | 1838 | *(SP body-extension) |
1839 | */ | 1839 | */ |
1840 | 1840 | ||
1841 | static int | 1841 | static int |
1842 | mailimap_body_ext_1part_3_parse(mailstream * fd, MMAPString * buffer, | 1842 | mailimap_body_ext_1part_3_parse(mailstream * fd, MMAPString * buffer, |
1843 | size_t * index, | 1843 | size_t * index, |
1844 | clist ** body_ext_list, | 1844 | clist ** body_ext_list, |
1845 | size_t progr_rate, | 1845 | size_t progr_rate, |
1846 | progress_function * progr_fun) | 1846 | progress_function * progr_fun) |
1847 | { | 1847 | { |
1848 | size_t cur_token; | 1848 | size_t cur_token; |
1849 | int r; | 1849 | int r; |
1850 | 1850 | ||
1851 | cur_token = * index; | 1851 | cur_token = * index; |
1852 | * body_ext_list = NULL; | 1852 | * body_ext_list = NULL; |
1853 | 1853 | ||
1854 | r = mailimap_space_parse(fd, buffer, &cur_token); | 1854 | r = mailimap_space_parse(fd, buffer, &cur_token); |
1855 | if (r != MAILIMAP_NO_ERROR) | 1855 | if (r != MAILIMAP_NO_ERROR) |
1856 | return r; | 1856 | return r; |
1857 | 1857 | ||
1858 | r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, | 1858 | r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, |
1859 | body_ext_list, | 1859 | body_ext_list, |
1860 | (mailimap_struct_parser *) | 1860 | (mailimap_struct_parser *) |
1861 | mailimap_body_extension_parse, | 1861 | mailimap_body_extension_parse, |
1862 | (mailimap_struct_destructor *) | 1862 | (mailimap_struct_destructor *) |
1863 | mailimap_body_extension_free, | 1863 | mailimap_body_extension_free, |
1864 | progr_rate, progr_fun); | 1864 | progr_rate, progr_fun); |
1865 | if (r != MAILIMAP_NO_ERROR) | 1865 | if (r != MAILIMAP_NO_ERROR) |
1866 | return r; | 1866 | return r; |
1867 | 1867 | ||
1868 | * index = cur_token; | 1868 | * index = cur_token; |
1869 | 1869 | ||
1870 | return MAILIMAP_NO_ERROR; | 1870 | return MAILIMAP_NO_ERROR; |
1871 | } | 1871 | } |
1872 | 1872 | ||
1873 | 1873 | ||
1874 | /* | 1874 | /* |
1875 | [SP body-fld-lang | 1875 | [SP body-fld-lang |
1876 | *(SP body-extension)]] | 1876 | *(SP body-extension)]] |
1877 | */ | 1877 | */ |
1878 | 1878 | ||
1879 | static int | 1879 | static int |
1880 | mailimap_body_ext_1part_2_parse(mailstream * fd, MMAPString * buffer, | 1880 | mailimap_body_ext_1part_2_parse(mailstream * fd, MMAPString * buffer, |
1881 | size_t * index, | 1881 | size_t * index, |
1882 | struct mailimap_body_fld_lang ** fld_lang, | 1882 | struct mailimap_body_fld_lang ** fld_lang, |
1883 | clist ** body_ext_list, | 1883 | clist ** body_ext_list, |
1884 | size_t progr_rate, | 1884 | size_t progr_rate, |
1885 | progress_function * progr_fun) | 1885 | progress_function * progr_fun) |
1886 | { | 1886 | { |
1887 | size_t cur_token; | 1887 | size_t cur_token; |
1888 | int r; | 1888 | int r; |
1889 | 1889 | ||
1890 | cur_token = * index; | 1890 | cur_token = * index; |
1891 | * fld_lang = NULL; | 1891 | * fld_lang = NULL; |
1892 | * body_ext_list = NULL; | 1892 | * body_ext_list = NULL; |
1893 | 1893 | ||
1894 | r = mailimap_space_parse(fd, buffer, &cur_token); | 1894 | r = mailimap_space_parse(fd, buffer, &cur_token); |
1895 | if (r != MAILIMAP_NO_ERROR) | 1895 | if (r != MAILIMAP_NO_ERROR) |
1896 | return r; | 1896 | return r; |
1897 | 1897 | ||
1898 | r = mailimap_body_fld_lang_parse(fd, buffer, &cur_token, fld_lang, | 1898 | r = mailimap_body_fld_lang_parse(fd, buffer, &cur_token, fld_lang, |
1899 | progr_rate, progr_fun); | 1899 | progr_rate, progr_fun); |
1900 | if (r != MAILIMAP_NO_ERROR) | 1900 | if (r != MAILIMAP_NO_ERROR) |
1901 | return r; | 1901 | return r; |
1902 | 1902 | ||
1903 | r = mailimap_body_ext_1part_3_parse(fd, buffer, &cur_token, | 1903 | r = mailimap_body_ext_1part_3_parse(fd, buffer, &cur_token, |
1904 | body_ext_list, progr_rate, progr_fun); | 1904 | body_ext_list, progr_rate, progr_fun); |
1905 | if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) | 1905 | if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) |
1906 | return r; | 1906 | return r; |
1907 | 1907 | ||
1908 | * index = cur_token; | 1908 | * index = cur_token; |
1909 | 1909 | ||
1910 | return MAILIMAP_NO_ERROR; | 1910 | return MAILIMAP_NO_ERROR; |
1911 | } | 1911 | } |
1912 | 1912 | ||
1913 | 1913 | ||
1914 | /* | 1914 | /* |
1915 | SP body-fld-dsp [SP body-fld-lang | 1915 | SP body-fld-dsp [SP body-fld-lang |
1916 | *(SP body-extension)]] | 1916 | *(SP body-extension)]] |
1917 | */ | 1917 | */ |
1918 | 1918 | ||
1919 | static int | 1919 | static int |
1920 | mailimap_body_ext_1part_1_parse(mailstream * fd, MMAPString * buffer, | 1920 | mailimap_body_ext_1part_1_parse(mailstream * fd, MMAPString * buffer, |
1921 | size_t * index, | 1921 | size_t * index, |
1922 | struct mailimap_body_fld_dsp ** fld_dsp, | 1922 | struct mailimap_body_fld_dsp ** fld_dsp, |
1923 | struct mailimap_body_fld_lang ** fld_lang, | 1923 | struct mailimap_body_fld_lang ** fld_lang, |
1924 | clist ** body_ext_list, | 1924 | clist ** body_ext_list, |
1925 | size_t progr_rate, | 1925 | size_t progr_rate, |
1926 | progress_function * progr_fun) | 1926 | progress_function * progr_fun) |
1927 | { | 1927 | { |
1928 | size_t cur_token; | 1928 | size_t cur_token; |
1929 | int r; | 1929 | int r; |
1930 | 1930 | ||
1931 | cur_token = * index; | 1931 | cur_token = * index; |
1932 | * fld_dsp = NULL; | 1932 | * fld_dsp = NULL; |
1933 | * fld_lang = NULL; | 1933 | * fld_lang = NULL; |
1934 | * body_ext_list = NULL; | 1934 | * body_ext_list = NULL; |
1935 | 1935 | ||
1936 | r = mailimap_space_parse(fd, buffer, &cur_token); | 1936 | r = mailimap_space_parse(fd, buffer, &cur_token); |
1937 | if (r != MAILIMAP_NO_ERROR) | 1937 | if (r != MAILIMAP_NO_ERROR) |
1938 | return r; | 1938 | return r; |
1939 | 1939 | ||
1940 | r = mailimap_body_fld_dsp_parse(fd, buffer, &cur_token, fld_dsp, | 1940 | r = mailimap_body_fld_dsp_parse(fd, buffer, &cur_token, fld_dsp, |
1941 | progr_rate, progr_fun); | 1941 | progr_rate, progr_fun); |
1942 | if (r != MAILIMAP_NO_ERROR) | 1942 | if (r != MAILIMAP_NO_ERROR) |
1943 | return r; | 1943 | return r; |
1944 | 1944 | ||
1945 | r = mailimap_body_ext_1part_2_parse(fd, buffer, &cur_token, | 1945 | r = mailimap_body_ext_1part_2_parse(fd, buffer, &cur_token, |
1946 | fld_lang, body_ext_list, | 1946 | fld_lang, body_ext_list, |
1947 | progr_rate, progr_fun); | 1947 | progr_rate, progr_fun); |
1948 | if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) | 1948 | if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) |
1949 | return r; | 1949 | return r; |
1950 | 1950 | ||
1951 | * index = cur_token; | 1951 | * index = cur_token; |
1952 | 1952 | ||
1953 | return MAILIMAP_NO_ERROR; | 1953 | return MAILIMAP_NO_ERROR; |
1954 | } | 1954 | } |
1955 | 1955 | ||
1956 | /* | 1956 | /* |
1957 | body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang | 1957 | body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang |
1958 | *(SP body-extension)]] | 1958 | *(SP body-extension)]] |
1959 | ; MUST NOT be returned on non-extensible | 1959 | ; MUST NOT be returned on non-extensible |
1960 | ; "BODY" fetch | 1960 | ; "BODY" fetch |
1961 | */ | 1961 | */ |
1962 | 1962 | ||
1963 | static int | 1963 | static int |
1964 | mailimap_body_ext_1part_parse(mailstream * fd, MMAPString * buffer, | 1964 | mailimap_body_ext_1part_parse(mailstream * fd, MMAPString * buffer, |
1965 | size_t * index, | 1965 | size_t * index, |
1966 | struct mailimap_body_ext_1part ** result, | 1966 | struct mailimap_body_ext_1part ** result, |
1967 | size_t progr_rate, | 1967 | size_t progr_rate, |
1968 | progress_function * progr_fun) | 1968 | progress_function * progr_fun) |
1969 | { | 1969 | { |
1970 | size_t cur_token; | 1970 | size_t cur_token; |
1971 | 1971 | ||
1972 | char * fld_md5; | 1972 | char * fld_md5; |
1973 | struct mailimap_body_fld_dsp * fld_dsp; | 1973 | struct mailimap_body_fld_dsp * fld_dsp; |
1974 | struct mailimap_body_fld_lang * fld_lang; | 1974 | struct mailimap_body_fld_lang * fld_lang; |
1975 | clist * body_ext_list; | 1975 | clist * body_ext_list; |
1976 | int r; | 1976 | int r; |
1977 | int res; | 1977 | int res; |
1978 | 1978 | ||
1979 | struct mailimap_body_ext_1part * ext_1part; | 1979 | struct mailimap_body_ext_1part * ext_1part; |
1980 | 1980 | ||
1981 | cur_token = * index; | 1981 | cur_token = * index; |
1982 | 1982 | ||
1983 | fld_md5 = NULL; | 1983 | fld_md5 = NULL; |
1984 | fld_dsp = NULL; | 1984 | fld_dsp = NULL; |
1985 | fld_lang = NULL; | 1985 | fld_lang = NULL; |
1986 | body_ext_list = NULL; | 1986 | body_ext_list = NULL; |
1987 | 1987 | ||
1988 | r = mailimap_body_fld_md5_parse(fd, buffer, &cur_token, &fld_md5, | 1988 | r = mailimap_body_fld_md5_parse(fd, buffer, &cur_token, &fld_md5, |
1989 | progr_rate, progr_fun); | 1989 | progr_rate, progr_fun); |
1990 | if (r != MAILIMAP_NO_ERROR) { | 1990 | if (r != MAILIMAP_NO_ERROR) { |
1991 | res = r; | 1991 | res = r; |
1992 | goto err; | 1992 | goto err; |
1993 | } | 1993 | } |
1994 | 1994 | ||
1995 | r = mailimap_body_ext_1part_1_parse(fd, buffer, &cur_token, | 1995 | r = mailimap_body_ext_1part_1_parse(fd, buffer, &cur_token, |
1996 | &fld_dsp, | 1996 | &fld_dsp, |
1997 | &fld_lang, | 1997 | &fld_lang, |
1998 | &body_ext_list, | 1998 | &body_ext_list, |
1999 | progr_rate, progr_fun); | 1999 | progr_rate, progr_fun); |
2000 | if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) { | 2000 | if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) { |
2001 | res = r; | 2001 | res = r; |
2002 | goto free; | 2002 | goto free; |
2003 | } | 2003 | } |
2004 | 2004 | ||
2005 | ext_1part = mailimap_body_ext_1part_new(fld_md5, fld_dsp, fld_lang, | 2005 | ext_1part = mailimap_body_ext_1part_new(fld_md5, fld_dsp, fld_lang, |
2006 | body_ext_list); | 2006 | body_ext_list); |
2007 | 2007 | ||
2008 | if (ext_1part == NULL) { | 2008 | if (ext_1part == NULL) { |
2009 | res = MAILIMAP_ERROR_MEMORY; | 2009 | res = MAILIMAP_ERROR_MEMORY; |
2010 | goto free; | 2010 | goto free; |
2011 | } | 2011 | } |
2012 | 2012 | ||
2013 | * result = ext_1part; | 2013 | * result = ext_1part; |
2014 | * index = cur_token; | 2014 | * index = cur_token; |
2015 | 2015 | ||
2016 | return MAILIMAP_NO_ERROR; | 2016 | return MAILIMAP_NO_ERROR; |
2017 | 2017 | ||
2018 | free: | 2018 | free: |
2019 | if (body_ext_list) { | 2019 | if (body_ext_list) { |
2020 | clist_foreach(body_ext_list, (clist_func) mailimap_body_extension_free, | 2020 | clist_foreach(body_ext_list, (clist_func) mailimap_body_extension_free, |
2021 | NULL); | 2021 | NULL); |
2022 | clist_free(body_ext_list); | 2022 | clist_free(body_ext_list); |
2023 | } | 2023 | } |
2024 | if (fld_lang) | 2024 | if (fld_lang) |
2025 | mailimap_body_fld_lang_free(fld_lang); | 2025 | mailimap_body_fld_lang_free(fld_lang); |
2026 | if (fld_dsp) | 2026 | if (fld_dsp) |
2027 | mailimap_body_fld_dsp_free(fld_dsp); | 2027 | mailimap_body_fld_dsp_free(fld_dsp); |
2028 | mailimap_body_fld_md5_free(fld_md5); | 2028 | mailimap_body_fld_md5_free(fld_md5); |
2029 | err: | 2029 | err: |
2030 | return res; | 2030 | return res; |
2031 | } | 2031 | } |
2032 | 2032 | ||
2033 | 2033 | ||
2034 | /* | 2034 | /* |
2035 | body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang | 2035 | body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang |
2036 | *(SP body-extension)]] | 2036 | *(SP body-extension)]] |
2037 | ; MUST NOT be returned on non-extensible | 2037 | ; MUST NOT be returned on non-extensible |
2038 | ; "BODY" fetch | 2038 | ; "BODY" fetch |
2039 | */ | 2039 | */ |
2040 | 2040 | ||
2041 | static int | 2041 | static int |
2042 | mailimap_body_ext_mpart_parse(mailstream * fd, MMAPString * buffer, | 2042 | mailimap_body_ext_mpart_parse(mailstream * fd, MMAPString * buffer, |
2043 | size_t * index, | 2043 | size_t * index, |
2044 | struct mailimap_body_ext_mpart ** result, | 2044 | struct mailimap_body_ext_mpart ** result, |
2045 | size_t progr_rate, | 2045 | size_t progr_rate, |
2046 | progress_function * progr_fun) | 2046 | progress_function * progr_fun) |
2047 | { | 2047 | { |
2048 | size_t cur_token; | 2048 | size_t cur_token; |
2049 | 2049 | ||
2050 | struct mailimap_body_fld_dsp * fld_dsp; | 2050 | struct mailimap_body_fld_dsp * fld_dsp; |
2051 | struct mailimap_body_fld_lang * fld_lang; | 2051 | struct mailimap_body_fld_lang * fld_lang; |
2052 | struct mailimap_body_fld_param * fld_param; | 2052 | struct mailimap_body_fld_param * fld_param; |
2053 | clist * body_ext_list; | 2053 | clist * body_ext_list; |
2054 | 2054 | ||
2055 | struct mailimap_body_ext_mpart * ext_mpart; | 2055 | struct mailimap_body_ext_mpart * ext_mpart; |
2056 | int r; | 2056 | int r; |
2057 | int res; | 2057 | int res; |
2058 | 2058 | ||
2059 | cur_token = * index; | 2059 | cur_token = * index; |
2060 | 2060 | ||
2061 | fld_param = NULL; | 2061 | fld_param = NULL; |
2062 | fld_dsp = NULL; | 2062 | fld_dsp = NULL; |
2063 | fld_lang = NULL; | 2063 | fld_lang = NULL; |
2064 | body_ext_list = NULL; | 2064 | body_ext_list = NULL; |
2065 | 2065 | ||
2066 | r = mailimap_body_fld_param_parse(fd, buffer, &cur_token, &fld_param, | 2066 | r = mailimap_body_fld_param_parse(fd, buffer, &cur_token, &fld_param, |
2067 | progr_rate, progr_fun); | 2067 | progr_rate, progr_fun); |
2068 | if (r != MAILIMAP_NO_ERROR) { | 2068 | if (r != MAILIMAP_NO_ERROR) { |
2069 | res = r; | 2069 | res = r; |
2070 | goto err; | 2070 | goto err; |
2071 | } | 2071 | } |
2072 | 2072 | ||
2073 | r = mailimap_body_ext_1part_1_parse(fd, buffer, &cur_token, | 2073 | r = mailimap_body_ext_1part_1_parse(fd, buffer, &cur_token, |
2074 | &fld_dsp, | 2074 | &fld_dsp, |
2075 | &fld_lang, | 2075 | &fld_lang, |
2076 | &body_ext_list, | 2076 | &body_ext_list, |
2077 | progr_rate, progr_fun); | 2077 | progr_rate, progr_fun); |
2078 | if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) { | 2078 | if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) { |
2079 | res = r; | 2079 | res = r; |
2080 | goto free; | 2080 | goto free; |
2081 | } | 2081 | } |
2082 | 2082 | ||
2083 | ext_mpart = mailimap_body_ext_mpart_new(fld_param, fld_dsp, fld_lang, | 2083 | ext_mpart = mailimap_body_ext_mpart_new(fld_param, fld_dsp, fld_lang, |
2084 | body_ext_list); | 2084 | body_ext_list); |
2085 | if (ext_mpart == NULL) { | 2085 | if (ext_mpart == NULL) { |
2086 | res = MAILIMAP_ERROR_MEMORY; | 2086 | res = MAILIMAP_ERROR_MEMORY; |
2087 | goto free; | 2087 | goto free; |
2088 | } | 2088 | } |
2089 | 2089 | ||
2090 | * result = ext_mpart; | 2090 | * result = ext_mpart; |
2091 | * index = cur_token; | 2091 | * index = cur_token; |
2092 | 2092 | ||
2093 | return MAILIMAP_NO_ERROR; | 2093 | return MAILIMAP_NO_ERROR; |
2094 | 2094 | ||
2095 | free: | 2095 | free: |
2096 | if (body_ext_list) { | 2096 | if (body_ext_list) { |
2097 | clist_foreach(body_ext_list, (clist_func) mailimap_body_extension_free, | 2097 | clist_foreach(body_ext_list, (clist_func) mailimap_body_extension_free, |
2098 | NULL); | 2098 | NULL); |
2099 | clist_free(body_ext_list); | 2099 | clist_free(body_ext_list); |
2100 | } | 2100 | } |
2101 | if (fld_lang) | 2101 | if (fld_lang) |
2102 | mailimap_body_fld_lang_free(fld_lang); | 2102 | mailimap_body_fld_lang_free(fld_lang); |
2103 | if (fld_dsp) | 2103 | if (fld_dsp) |
2104 | mailimap_body_fld_dsp_free(fld_dsp); | 2104 | mailimap_body_fld_dsp_free(fld_dsp); |
2105 | if (fld_param != NULL) | 2105 | if (fld_param != NULL) |
2106 | mailimap_body_fld_param_free(fld_param); | 2106 | mailimap_body_fld_param_free(fld_param); |
2107 | err: | 2107 | err: |
2108 | return res; | 2108 | return res; |
2109 | } | 2109 | } |
2110 | 2110 | ||
2111 | /* | 2111 | /* |
2112 | body-fields = body-fld-param SP body-fld-id SP body-fld-desc SP | 2112 | body-fields = body-fld-param SP body-fld-id SP body-fld-desc SP |
2113 | body-fld-enc SP body-fld-octets | 2113 | body-fld-enc SP body-fld-octets |
2114 | */ | 2114 | */ |
2115 | 2115 | ||
2116 | static int | 2116 | static int |
2117 | mailimap_body_fields_parse(mailstream * fd, MMAPString * buffer, | 2117 | mailimap_body_fields_parse(mailstream * fd, MMAPString * buffer, |
2118 | size_t * index, | 2118 | size_t * index, |
2119 | struct mailimap_body_fields ** result, | 2119 | struct mailimap_body_fields ** result, |
2120 | size_t progr_rate, | 2120 | size_t progr_rate, |
2121 | progress_function * progr_fun) | 2121 | progress_function * progr_fun) |
2122 | { | 2122 | { |
2123 | struct mailimap_body_fields * body_fields; | 2123 | struct mailimap_body_fields * body_fields; |
2124 | size_t cur_token; | 2124 | size_t cur_token; |
2125 | struct mailimap_body_fld_param * body_fld_param; | 2125 | struct mailimap_body_fld_param * body_fld_param; |
2126 | char * body_fld_id; | 2126 | char * body_fld_id; |
2127 | char * body_fld_desc; | 2127 | char * body_fld_desc; |
2128 | struct mailimap_body_fld_enc * body_fld_enc; | 2128 | struct mailimap_body_fld_enc * body_fld_enc; |
2129 | uint32_t body_fld_octets; | 2129 | uint32_t body_fld_octets; |
2130 | int r; | 2130 | int r; |
2131 | int res; | 2131 | int res; |
2132 | 2132 | ||
2133 | body_fld_param = NULL; | 2133 | body_fld_param = NULL; |
2134 | body_fld_id = NULL; | 2134 | body_fld_id = NULL; |
2135 | body_fld_desc = NULL; | 2135 | body_fld_desc = NULL; |
2136 | body_fld_enc = NULL; | 2136 | body_fld_enc = NULL; |
2137 | body_fld_octets = 0; | 2137 | body_fld_octets = 0; |
2138 | 2138 | ||
2139 | cur_token = * index; | 2139 | cur_token = * index; |
2140 | 2140 | ||
2141 | r = mailimap_body_fld_param_parse(fd, buffer, &cur_token, &body_fld_param, | 2141 | r = mailimap_body_fld_param_parse(fd, buffer, &cur_token, &body_fld_param, |
2142 | progr_rate, progr_fun); | 2142 | progr_rate, progr_fun); |
2143 | if (r != MAILIMAP_NO_ERROR) { | 2143 | if (r != MAILIMAP_NO_ERROR) { |
2144 | res = r; | 2144 | res = r; |
2145 | goto err; | 2145 | goto err; |
2146 | } | 2146 | } |
2147 | 2147 | ||
2148 | r = mailimap_space_parse(fd, buffer, &cur_token); | 2148 | r = mailimap_space_parse(fd, buffer, &cur_token); |
2149 | if (r != MAILIMAP_NO_ERROR) { | 2149 | if (r != MAILIMAP_NO_ERROR) { |
2150 | res = r; | 2150 | res = r; |
2151 | goto fld_param_free; | 2151 | goto fld_param_free; |
2152 | } | 2152 | } |
2153 | 2153 | ||
2154 | r = mailimap_body_fld_id_parse(fd, buffer, &cur_token, &body_fld_id, | 2154 | r = mailimap_body_fld_id_parse(fd, buffer, &cur_token, &body_fld_id, |
2155 | progr_rate, progr_fun); | 2155 | progr_rate, progr_fun); |
2156 | if (r != MAILIMAP_NO_ERROR) { | 2156 | if (r != MAILIMAP_NO_ERROR) { |
2157 | res = r; | 2157 | res = r; |
2158 | goto fld_param_free; | 2158 | goto fld_param_free; |
2159 | } | 2159 | } |
2160 | 2160 | ||
2161 | r = mailimap_space_parse(fd, buffer, &cur_token); | 2161 | r = mailimap_space_parse(fd, buffer, &cur_token); |
2162 | if (r != MAILIMAP_NO_ERROR) { | 2162 | if (r != MAILIMAP_NO_ERROR) { |
2163 | res = r; | 2163 | res = r; |
2164 | goto fld_id_free; | 2164 | goto fld_id_free; |
2165 | } | 2165 | } |
2166 | 2166 | ||
2167 | r = mailimap_body_fld_desc_parse(fd, buffer, &cur_token, &body_fld_desc, | 2167 | r = mailimap_body_fld_desc_parse(fd, buffer, &cur_token, &body_fld_desc, |
2168 | progr_rate, progr_fun); | 2168 | progr_rate, progr_fun); |
2169 | if (r != MAILIMAP_NO_ERROR) { | 2169 | if (r != MAILIMAP_NO_ERROR) { |
2170 | res = r; | 2170 | res = r; |
2171 | goto fld_id_free; | 2171 | goto fld_id_free; |
2172 | } | 2172 | } |
2173 | 2173 | ||
2174 | r = mailimap_space_parse(fd, buffer, &cur_token); | 2174 | r = mailimap_space_parse(fd, buffer, &cur_token); |
2175 | if (r != MAILIMAP_NO_ERROR) { | 2175 | if (r != MAILIMAP_NO_ERROR) { |
2176 | res = r; | 2176 | res = r; |
2177 | goto fld_desc_free; | 2177 | goto fld_desc_free; |
2178 | } | 2178 | } |
2179 | 2179 | ||
2180 | r = mailimap_body_fld_enc_parse(fd, buffer, &cur_token, &body_fld_enc, | 2180 | r = mailimap_body_fld_enc_parse(fd, buffer, &cur_token, &body_fld_enc, |
2181 | progr_rate, progr_fun); | 2181 | progr_rate, progr_fun); |
2182 | if (r != MAILIMAP_NO_ERROR) { | 2182 | if (r != MAILIMAP_NO_ERROR) { |
2183 | res = r; | 2183 | res = r; |
2184 | goto fld_desc_free; | 2184 | goto fld_desc_free; |
2185 | } | 2185 | } |
2186 | 2186 | ||
2187 | r = mailimap_space_parse(fd, buffer, &cur_token); | 2187 | r = mailimap_space_parse(fd, buffer, &cur_token); |
2188 | if (r != MAILIMAP_NO_ERROR) { | 2188 | if (r != MAILIMAP_NO_ERROR) { |
2189 | res = r; | 2189 | res = r; |
2190 | goto fld_enc_free; | 2190 | goto fld_enc_free; |
2191 | } | 2191 | } |
2192 | 2192 | ||
2193 | r = mailimap_body_fld_octets_parse(fd, buffer, &cur_token, | 2193 | r = mailimap_body_fld_octets_parse(fd, buffer, &cur_token, |
2194 | &body_fld_octets); | 2194 | &body_fld_octets); |
2195 | if (r != MAILIMAP_NO_ERROR) { | 2195 | if (r != MAILIMAP_NO_ERROR) { |
2196 | res = r; | 2196 | res = r; |
2197 | goto fld_enc_free; | 2197 | goto fld_enc_free; |
2198 | } | 2198 | } |
2199 | 2199 | ||
2200 | body_fields = mailimap_body_fields_new(body_fld_param, | 2200 | body_fields = mailimap_body_fields_new(body_fld_param, |
2201 | body_fld_id, | 2201 | body_fld_id, |
2202 | body_fld_desc, | 2202 | body_fld_desc, |
2203 | body_fld_enc, | 2203 | body_fld_enc, |
2204 | body_fld_octets); | 2204 | body_fld_octets); |
2205 | if (body_fields == NULL) { | 2205 | if (body_fields == NULL) { |
2206 | res = MAILIMAP_ERROR_MEMORY; | 2206 | res = MAILIMAP_ERROR_MEMORY; |
2207 | goto fld_enc_free; | 2207 | goto fld_enc_free; |
2208 | } | 2208 | } |
2209 | 2209 | ||
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, |
2596 | size_t * index, char ** result, | 2614 | size_t * index, char ** result, |
2597 | size_t progr_rate, | 2615 | size_t progr_rate, |
2598 | progress_function * progr_fun) | 2616 | progress_function * progr_fun) |
2599 | { | 2617 | { |
2600 | return mailimap_nstring_parse(fd, buffer, index, result, NULL, | 2618 | return mailimap_nstring_parse(fd, buffer, index, result, NULL, |
2601 | progr_rate, progr_fun); | 2619 | progr_rate, progr_fun); |
2602 | } | 2620 | } |
2603 | 2621 | ||
2604 | /* | 2622 | /* |
2605 | body-fld-octets = number | 2623 | body-fld-octets = number |
2606 | */ | 2624 | */ |
2607 | 2625 | ||
2608 | static int mailimap_body_fld_octets_parse(mailstream * fd, | 2626 | static int mailimap_body_fld_octets_parse(mailstream * fd, |
2609 | MMAPString * buffer, size_t * index, | 2627 | MMAPString * buffer, size_t * index, |
2610 | uint32_t * result) | 2628 | uint32_t * result) |
2611 | { | 2629 | { |
2612 | return mailimap_number_parse(fd, buffer, index, result); | 2630 | return mailimap_number_parse(fd, buffer, index, result); |
2613 | } | 2631 | } |
2614 | 2632 | ||
2615 | /* | 2633 | /* |
2616 | body-fld-param = "(" string SP string *(SP string SP string) ")" / nil | 2634 | body-fld-param = "(" string SP string *(SP string SP string) ")" / nil |
2617 | */ | 2635 | */ |
2618 | 2636 | ||
2619 | /* | 2637 | /* |
2620 | string SP string | 2638 | string SP string |
2621 | */ | 2639 | */ |
2622 | 2640 | ||
2623 | static int | 2641 | static int |
2624 | mailimap_single_body_fld_param_parse(mailstream * fd, MMAPString * buffer, | 2642 | mailimap_single_body_fld_param_parse(mailstream * fd, MMAPString * buffer, |
2625 | size_t * index, | 2643 | size_t * index, |
2626 | struct mailimap_single_body_fld_param ** | 2644 | struct mailimap_single_body_fld_param ** |
2627 | result, | 2645 | result, |
2628 | size_t progr_rate, | 2646 | size_t progr_rate, |
2629 | progress_function * progr_fun) | 2647 | progress_function * progr_fun) |
2630 | { | 2648 | { |
2631 | struct mailimap_single_body_fld_param * param; | 2649 | struct mailimap_single_body_fld_param * param; |
2632 | char * name; | 2650 | char * name; |
2633 | char * value; | 2651 | char * value; |
2634 | size_t cur_token; | 2652 | size_t cur_token; |
2635 | int r; | 2653 | int r; |
2636 | int res; | 2654 | int res; |
2637 | 2655 | ||
2638 | cur_token = * index; | 2656 | cur_token = * index; |
2639 | 2657 | ||
2640 | name = NULL; | 2658 | name = NULL; |
2641 | value = NULL; | 2659 | value = NULL; |
2642 | 2660 | ||
2643 | r = mailimap_string_parse(fd, buffer, &cur_token, &name, NULL, | 2661 | r = mailimap_string_parse(fd, buffer, &cur_token, &name, NULL, |
2644 | progr_rate, progr_fun); | 2662 | progr_rate, progr_fun); |
2645 | if (r != MAILIMAP_NO_ERROR) { | 2663 | if (r != MAILIMAP_NO_ERROR) { |
2646 | res = r; | 2664 | res = r; |
2647 | goto err; | 2665 | goto err; |
2648 | } | 2666 | } |
2649 | 2667 | ||
2650 | r = mailimap_space_parse(fd, buffer, &cur_token); | 2668 | r = mailimap_space_parse(fd, buffer, &cur_token); |
2651 | if (r != MAILIMAP_NO_ERROR) { | 2669 | if (r != MAILIMAP_NO_ERROR) { |
2652 | res = r; | 2670 | res = r; |
2653 | goto free_name; | 2671 | goto free_name; |
2654 | } | 2672 | } |
2655 | 2673 | ||
2656 | r = mailimap_string_parse(fd, buffer, &cur_token, &value, NULL, | 2674 | r = mailimap_string_parse(fd, buffer, &cur_token, &value, NULL, |
2657 | progr_rate, progr_fun); | 2675 | progr_rate, progr_fun); |
2658 | if (r != MAILIMAP_NO_ERROR) { | 2676 | if (r != MAILIMAP_NO_ERROR) { |
2659 | res = r; | 2677 | res = r; |
2660 | goto free_name; | 2678 | goto free_name; |
2661 | } | 2679 | } |
2662 | 2680 | ||
2663 | param = mailimap_single_body_fld_param_new(name, value); | 2681 | param = mailimap_single_body_fld_param_new(name, value); |
2664 | if (param == NULL) { | 2682 | if (param == NULL) { |
2665 | res = MAILIMAP_ERROR_MEMORY; | 2683 | res = MAILIMAP_ERROR_MEMORY; |
2666 | goto free_value; | 2684 | goto free_value; |
2667 | } | 2685 | } |
2668 | 2686 | ||
2669 | * result = param; | 2687 | * result = param; |
2670 | * index = cur_token; | 2688 | * index = cur_token; |
2671 | 2689 | ||
2672 | return MAILIMAP_NO_ERROR; | 2690 | return MAILIMAP_NO_ERROR; |
2673 | 2691 | ||
2674 | free_value: | 2692 | free_value: |
2675 | mailimap_string_free(name); | 2693 | mailimap_string_free(name); |
2676 | free_name: | 2694 | free_name: |
2677 | mailimap_string_free(value); | 2695 | mailimap_string_free(value); |
2678 | err: | 2696 | err: |
2679 | return res; | 2697 | return res; |
2680 | } | 2698 | } |
2681 | 2699 | ||
2682 | /* | 2700 | /* |
2683 | body-fld-param = "(" string SP string *(SP string SP string) ")" / nil | 2701 | body-fld-param = "(" string SP string *(SP string SP string) ")" / nil |
2684 | */ | 2702 | */ |
2685 | 2703 | ||
2686 | static int | 2704 | static int |
2687 | mailimap_body_fld_param_parse(mailstream * fd, | 2705 | mailimap_body_fld_param_parse(mailstream * fd, |
2688 | MMAPString * buffer, size_t * index, | 2706 | MMAPString * buffer, size_t * index, |
2689 | struct mailimap_body_fld_param ** result, | 2707 | struct mailimap_body_fld_param ** result, |
2690 | size_t progr_rate, | 2708 | size_t progr_rate, |
2691 | progress_function * progr_fun) | 2709 | progress_function * progr_fun) |
2692 | { | 2710 | { |
2693 | size_t cur_token; | 2711 | size_t cur_token; |
2694 | clist * param_list; | 2712 | clist * param_list; |
2695 | struct mailimap_body_fld_param * fld_param; | 2713 | struct mailimap_body_fld_param * fld_param; |
2696 | int r; | 2714 | int r; |
2697 | int res; | 2715 | int res; |
2698 | 2716 | ||
2699 | param_list = NULL; | 2717 | param_list = NULL; |
2700 | cur_token = * index; | 2718 | cur_token = * index; |
2701 | 2719 | ||
2702 | r = mailimap_nil_parse(fd, buffer, &cur_token); | 2720 | r = mailimap_nil_parse(fd, buffer, &cur_token); |
2703 | if (r == MAILIMAP_NO_ERROR) { | 2721 | if (r == MAILIMAP_NO_ERROR) { |
2704 | * result = NULL; | 2722 | * result = NULL; |
2705 | * index = cur_token; | 2723 | * index = cur_token; |
2706 | return MAILIMAP_NO_ERROR; | 2724 | return MAILIMAP_NO_ERROR; |
2707 | } | 2725 | } |
2708 | 2726 | ||
2709 | if (r != MAILIMAP_ERROR_PARSE) { | 2727 | if (r != MAILIMAP_ERROR_PARSE) { |
2710 | res = r; | 2728 | res = r; |
2711 | goto err; | 2729 | goto err; |
2712 | } | 2730 | } |
2713 | 2731 | ||
2714 | r = mailimap_oparenth_parse(fd, buffer, &cur_token); | 2732 | r = mailimap_oparenth_parse(fd, buffer, &cur_token); |
2715 | if (r != MAILIMAP_NO_ERROR) { | 2733 | if (r != MAILIMAP_NO_ERROR) { |
2716 | res = r; | 2734 | res = r; |
2717 | goto err; | 2735 | goto err; |
2718 | } | 2736 | } |
2719 | 2737 | ||
2720 | r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, ¶m_list, | 2738 | r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, ¶m_list, |
2721 | (mailimap_struct_parser *) | 2739 | (mailimap_struct_parser *) |
2722 | mailimap_single_body_fld_param_parse, | 2740 | mailimap_single_body_fld_param_parse, |
2723 | (mailimap_struct_destructor *) | 2741 | (mailimap_struct_destructor *) |
2724 | mailimap_single_body_fld_param_free, | 2742 | mailimap_single_body_fld_param_free, |
2725 | progr_rate, progr_fun); | 2743 | progr_rate, progr_fun); |
2726 | if (r != MAILIMAP_NO_ERROR) { | 2744 | if (r != MAILIMAP_NO_ERROR) { |
2727 | res = r; | 2745 | res = r; |
2728 | goto err; | 2746 | goto err; |
2729 | } | 2747 | } |
2730 | 2748 | ||
2731 | r = mailimap_cparenth_parse(fd, buffer, &cur_token); | 2749 | r = mailimap_cparenth_parse(fd, buffer, &cur_token); |
2732 | if (r != MAILIMAP_NO_ERROR) { | 2750 | if (r != MAILIMAP_NO_ERROR) { |
2733 | res = r; | 2751 | res = r; |
2734 | goto free; | 2752 | goto free; |
2735 | } | 2753 | } |
2736 | 2754 | ||
2737 | fld_param = mailimap_body_fld_param_new(param_list); | 2755 | fld_param = mailimap_body_fld_param_new(param_list); |
2738 | if (fld_param == NULL) { | 2756 | if (fld_param == NULL) { |
2739 | res = MAILIMAP_ERROR_MEMORY; | 2757 | res = MAILIMAP_ERROR_MEMORY; |
2740 | goto free; | 2758 | goto free; |
2741 | } | 2759 | } |
2742 | 2760 | ||
2743 | * index = cur_token; | 2761 | * index = cur_token; |
2744 | * result = fld_param; | 2762 | * result = fld_param; |
2745 | 2763 | ||
2746 | return MAILIMAP_NO_ERROR; | 2764 | return MAILIMAP_NO_ERROR; |
2747 | 2765 | ||
2748 | free: | 2766 | free: |
2749 | clist_foreach(param_list, | 2767 | clist_foreach(param_list, |
2750 | (clist_func) mailimap_single_body_fld_param_free, | 2768 | (clist_func) mailimap_single_body_fld_param_free, |
2751 | NULL); | 2769 | NULL); |
2752 | clist_free(param_list); | 2770 | clist_free(param_list); |
2753 | err: | 2771 | err: |
2754 | return res; | 2772 | return res; |
2755 | } | 2773 | } |
2756 | 2774 | ||
2757 | /* | 2775 | /* |
2758 | body-type-1part = (body-type-basic / body-type-msg / body-type-text) | 2776 | body-type-1part = (body-type-basic / body-type-msg / body-type-text) |
2759 | [SP body-ext-1part] | 2777 | [SP body-ext-1part] |
2760 | */ | 2778 | */ |
2761 | 2779 | ||
2762 | static int | 2780 | static int |
2763 | mailimap_body_type_1part_parse(mailstream * fd, MMAPString * buffer, | 2781 | mailimap_body_type_1part_parse(mailstream * fd, MMAPString * buffer, |
2764 | size_t * index, | 2782 | size_t * index, |
2765 | struct mailimap_body_type_1part ** result, | 2783 | struct mailimap_body_type_1part ** result, |
2766 | size_t progr_rate, | 2784 | size_t progr_rate, |
2767 | progress_function * progr_fun) | 2785 | progress_function * progr_fun) |
2768 | { | 2786 | { |
2769 | size_t cur_token; | 2787 | size_t cur_token; |
2770 | struct mailimap_body_type_1part * body_type_1part; | 2788 | struct mailimap_body_type_1part * body_type_1part; |
2771 | struct mailimap_body_type_basic * body_type_basic; | 2789 | struct mailimap_body_type_basic * body_type_basic; |
2772 | struct mailimap_body_type_msg * body_type_msg; | 2790 | struct mailimap_body_type_msg * body_type_msg; |
2773 | struct mailimap_body_type_text * body_type_text; | 2791 | struct mailimap_body_type_text * body_type_text; |
2774 | struct mailimap_body_ext_1part * body_ext_1part; | 2792 | struct mailimap_body_ext_1part * body_ext_1part; |
2775 | int type; | 2793 | int type; |
2776 | size_t final_token; | 2794 | size_t final_token; |
2777 | int r; | 2795 | int r; |
2778 | int res; | 2796 | int res; |
2779 | 2797 | ||
2780 | cur_token = * index; | 2798 | cur_token = * index; |
2781 | 2799 | ||
2782 | body_type_basic = NULL; | 2800 | body_type_basic = NULL; |
2783 | body_type_msg = NULL; | 2801 | body_type_msg = NULL; |
2784 | body_type_text = NULL; | 2802 | body_type_text = NULL; |
2785 | body_ext_1part = NULL; | 2803 | body_ext_1part = NULL; |
2786 | 2804 | ||
2787 | type = MAILIMAP_BODY_TYPE_1PART_ERROR; /* XXX - removes a gcc warning */ | 2805 | type = MAILIMAP_BODY_TYPE_1PART_ERROR; /* XXX - removes a gcc warning */ |
2788 | 2806 | ||
2789 | r = mailimap_body_type_msg_parse(fd, buffer, &cur_token, | 2807 | r = mailimap_body_type_msg_parse(fd, buffer, &cur_token, |
2790 | &body_type_msg, | 2808 | &body_type_msg, |
2791 | progr_rate, progr_fun); | 2809 | progr_rate, progr_fun); |
2792 | if (r == MAILIMAP_NO_ERROR) | 2810 | if (r == MAILIMAP_NO_ERROR) |
2793 | type = MAILIMAP_BODY_TYPE_1PART_MSG; | 2811 | type = MAILIMAP_BODY_TYPE_1PART_MSG; |
2794 | 2812 | ||
2795 | if (r == MAILIMAP_ERROR_PARSE) { | 2813 | if (r == MAILIMAP_ERROR_PARSE) { |
2796 | r = mailimap_body_type_text_parse(fd, buffer, &cur_token, | 2814 | r = mailimap_body_type_text_parse(fd, buffer, &cur_token, |
2797 | &body_type_text, | 2815 | &body_type_text, |
2798 | progr_rate, progr_fun); | 2816 | progr_rate, progr_fun); |
2799 | if (r == MAILIMAP_NO_ERROR) | 2817 | if (r == MAILIMAP_NO_ERROR) |
2800 | type = MAILIMAP_BODY_TYPE_1PART_TEXT; | 2818 | type = MAILIMAP_BODY_TYPE_1PART_TEXT; |
2801 | } | 2819 | } |
2802 | 2820 | ||
2803 | if (r == MAILIMAP_ERROR_PARSE) { | 2821 | if (r == MAILIMAP_ERROR_PARSE) { |
2804 | r = mailimap_body_type_basic_parse(fd, buffer, &cur_token, | 2822 | r = mailimap_body_type_basic_parse(fd, buffer, &cur_token, |
2805 | &body_type_basic, | 2823 | &body_type_basic, |
2806 | progr_rate, progr_fun); | 2824 | progr_rate, progr_fun); |
2807 | if (r == MAILIMAP_NO_ERROR) | 2825 | if (r == MAILIMAP_NO_ERROR) |
2808 | type = MAILIMAP_BODY_TYPE_1PART_BASIC; | 2826 | type = MAILIMAP_BODY_TYPE_1PART_BASIC; |
2809 | } | 2827 | } |
2810 | 2828 | ||
2811 | if (r != MAILIMAP_NO_ERROR) { | 2829 | if (r != MAILIMAP_NO_ERROR) { |
2812 | res = r; | 2830 | res = r; |
2813 | goto err; | 2831 | goto err; |
2814 | } | 2832 | } |
2815 | 2833 | ||
2816 | final_token = cur_token; | 2834 | final_token = cur_token; |
2817 | body_ext_1part = NULL; | 2835 | body_ext_1part = NULL; |
2818 | 2836 | ||
2819 | r = mailimap_space_parse(fd, buffer, &cur_token); | 2837 | r = mailimap_space_parse(fd, buffer, &cur_token); |
2820 | 2838 | ||
2821 | if (r == MAILIMAP_NO_ERROR) { | 2839 | if (r == MAILIMAP_NO_ERROR) { |
2822 | r = mailimap_body_ext_1part_parse(fd, buffer, &cur_token, &body_ext_1part, | 2840 | r = mailimap_body_ext_1part_parse(fd, buffer, &cur_token, &body_ext_1part, |
2823 | progr_rate, progr_fun); | 2841 | progr_rate, progr_fun); |
2824 | if (r == MAILIMAP_NO_ERROR) | 2842 | if (r == MAILIMAP_NO_ERROR) |
2825 | final_token = cur_token; | 2843 | final_token = cur_token; |
2826 | else if (r == MAILIMAP_ERROR_PARSE) { | 2844 | else if (r == MAILIMAP_ERROR_PARSE) { |
2827 | /* do nothing */ | 2845 | /* do nothing */ |
2828 | } | 2846 | } |
2829 | else { | 2847 | else { |
2830 | res = r; | 2848 | res = r; |
2831 | goto free; | 2849 | goto free; |
2832 | } | 2850 | } |
2833 | } | 2851 | } |
2834 | else if (r == MAILIMAP_ERROR_PARSE) { | 2852 | else if (r == MAILIMAP_ERROR_PARSE) { |
2835 | /* do nothing */ | 2853 | /* do nothing */ |
2836 | } | 2854 | } |
2837 | else { | 2855 | else { |
2838 | res = r; | 2856 | res = r; |
2839 | goto free; | 2857 | goto free; |
2840 | } | 2858 | } |
2841 | 2859 | ||
2842 | body_type_1part = mailimap_body_type_1part_new(type, body_type_basic, | 2860 | body_type_1part = mailimap_body_type_1part_new(type, body_type_basic, |
2843 | body_type_msg, body_type_text, | 2861 | body_type_msg, body_type_text, |
2844 | body_ext_1part); | 2862 | body_ext_1part); |
2845 | if (body_type_1part == NULL) { | 2863 | if (body_type_1part == NULL) { |
2846 | res = MAILIMAP_ERROR_MEMORY; | 2864 | res = MAILIMAP_ERROR_MEMORY; |
2847 | goto free; | 2865 | goto free; |
2848 | } | 2866 | } |
2849 | 2867 | ||
2850 | * index = final_token; | 2868 | * index = final_token; |
2851 | * result = body_type_1part; | 2869 | * result = body_type_1part; |
2852 | 2870 | ||
2853 | return MAILIMAP_NO_ERROR; | 2871 | return MAILIMAP_NO_ERROR; |
2854 | 2872 | ||
2855 | free: | 2873 | free: |
2856 | if (body_type_basic) | 2874 | if (body_type_basic) |
2857 | mailimap_body_type_basic_free(body_type_basic); | 2875 | mailimap_body_type_basic_free(body_type_basic); |
2858 | if (body_type_msg) | 2876 | if (body_type_msg) |
2859 | mailimap_body_type_msg_free(body_type_msg); | 2877 | mailimap_body_type_msg_free(body_type_msg); |
2860 | if (body_type_text) | 2878 | if (body_type_text) |
2861 | mailimap_body_type_text_free(body_type_text); | 2879 | mailimap_body_type_text_free(body_type_text); |
2862 | if (body_ext_1part) | 2880 | if (body_ext_1part) |
2863 | mailimap_body_ext_1part_free(body_ext_1part); | 2881 | mailimap_body_ext_1part_free(body_ext_1part); |
2864 | err: | 2882 | err: |
2865 | return res; | 2883 | return res; |
2866 | } | 2884 | } |
2867 | 2885 | ||
2868 | /* | 2886 | /* |
2869 | body-type-basic = media-basic SP body-fields | 2887 | body-type-basic = media-basic SP body-fields |
2870 | ; MESSAGE subtype MUST NOT be "RFC822" | 2888 | ; MESSAGE subtype MUST NOT be "RFC822" |
2871 | */ | 2889 | */ |
2872 | 2890 | ||
2873 | static int | 2891 | static int |
2874 | mailimap_body_type_basic_parse(mailstream * fd, MMAPString * buffer, | 2892 | mailimap_body_type_basic_parse(mailstream * fd, MMAPString * buffer, |
2875 | size_t * index, | 2893 | size_t * index, |
2876 | struct mailimap_body_type_basic ** result, | 2894 | struct mailimap_body_type_basic ** result, |
2877 | size_t progr_rate, | 2895 | size_t progr_rate, |
2878 | progress_function * progr_fun) | 2896 | progress_function * progr_fun) |
2879 | { | 2897 | { |
2880 | size_t cur_token; | 2898 | size_t cur_token; |
2881 | struct mailimap_body_type_basic * body_type_basic; | 2899 | struct mailimap_body_type_basic * body_type_basic; |
2882 | struct mailimap_media_basic * media_basic; | 2900 | struct mailimap_media_basic * media_basic; |
2883 | struct mailimap_body_fields * body_fields; | 2901 | struct mailimap_body_fields * body_fields; |
2884 | int r; | 2902 | int r; |
2885 | int res; | 2903 | int res; |
2886 | 2904 | ||
2887 | cur_token = * index; | 2905 | cur_token = * index; |
2888 | 2906 | ||
2889 | media_basic = NULL; | 2907 | media_basic = NULL; |
2890 | body_fields = NULL; | 2908 | body_fields = NULL; |
2891 | 2909 | ||
2892 | r = mailimap_media_basic_parse(fd, buffer, &cur_token, &media_basic, | 2910 | r = mailimap_media_basic_parse(fd, buffer, &cur_token, &media_basic, |
2893 | progr_rate, progr_fun); | 2911 | progr_rate, progr_fun); |
2894 | if (r != MAILIMAP_NO_ERROR) { | 2912 | if (r != MAILIMAP_NO_ERROR) { |
2895 | res = r; | 2913 | res = r; |
2896 | goto err; | 2914 | goto err; |
2897 | } | 2915 | } |
2898 | 2916 | ||
2899 | r = mailimap_space_parse(fd, buffer, &cur_token); | 2917 | r = mailimap_space_parse(fd, buffer, &cur_token); |
2900 | if (r != MAILIMAP_NO_ERROR) { | 2918 | if (r != MAILIMAP_NO_ERROR) { |
2901 | res = r; | 2919 | res = r; |
2902 | goto free_media_basic; | 2920 | goto free_media_basic; |
2903 | } | 2921 | } |
2904 | 2922 | ||
2905 | r = mailimap_body_fields_parse(fd, buffer, &cur_token, &body_fields, | 2923 | r = mailimap_body_fields_parse(fd, buffer, &cur_token, &body_fields, |
2906 | progr_rate, progr_fun); | 2924 | progr_rate, progr_fun); |
2907 | if (r != MAILIMAP_NO_ERROR) { | 2925 | if (r != MAILIMAP_NO_ERROR) { |
2908 | res = r; | 2926 | res = r; |
2909 | goto free_media_basic; | 2927 | goto free_media_basic; |
2910 | } | 2928 | } |
2911 | 2929 | ||
2912 | body_type_basic = mailimap_body_type_basic_new(media_basic, body_fields); | 2930 | body_type_basic = mailimap_body_type_basic_new(media_basic, body_fields); |
2913 | if (body_type_basic == NULL) { | 2931 | if (body_type_basic == NULL) { |
2914 | res = MAILIMAP_ERROR_MEMORY; | 2932 | res = MAILIMAP_ERROR_MEMORY; |
2915 | goto free_body_fields; | 2933 | goto free_body_fields; |
2916 | } | 2934 | } |
2917 | 2935 | ||
2918 | * index = cur_token; | 2936 | * index = cur_token; |
2919 | * result = body_type_basic; | 2937 | * result = body_type_basic; |
2920 | 2938 | ||
2921 | return MAILIMAP_NO_ERROR; | 2939 | return MAILIMAP_NO_ERROR; |
2922 | 2940 | ||
2923 | free_body_fields: | 2941 | free_body_fields: |
2924 | mailimap_body_fields_free(body_fields); | 2942 | mailimap_body_fields_free(body_fields); |
2925 | free_media_basic: | 2943 | free_media_basic: |
2926 | mailimap_media_basic_free(media_basic); | 2944 | mailimap_media_basic_free(media_basic); |
2927 | err: | 2945 | err: |
2928 | return res; | 2946 | return res; |
2929 | } | 2947 | } |
2930 | 2948 | ||
2931 | /* | 2949 | /* |
2932 | body-type-mpart = 1*body SP media-subtype | 2950 | body-type-mpart = 1*body SP media-subtype |
2933 | [SP body-ext-mpart] | 2951 | [SP body-ext-mpart] |
2934 | */ | 2952 | */ |
2935 | 2953 | ||
2936 | static int | 2954 | static int |
2937 | mailimap_body_type_mpart_parse(mailstream * fd, | 2955 | mailimap_body_type_mpart_parse(mailstream * fd, |
2938 | MMAPString * buffer, | 2956 | MMAPString * buffer, |
2939 | size_t * index, | 2957 | size_t * index, |
2940 | struct mailimap_body_type_mpart ** result, | 2958 | struct mailimap_body_type_mpart ** result, |
2941 | size_t progr_rate, | 2959 | size_t progr_rate, |
2942 | progress_function * progr_fun) | 2960 | progress_function * progr_fun) |
2943 | { | 2961 | { |
2944 | struct mailimap_body_type_mpart * body_type_mpart; | 2962 | struct mailimap_body_type_mpart * body_type_mpart; |
2945 | clist * body_list; | 2963 | clist * body_list; |
2946 | size_t cur_token; | 2964 | size_t cur_token; |
2947 | size_t final_token; | 2965 | size_t final_token; |
2948 | char * media_subtype; | 2966 | char * media_subtype; |
2949 | struct mailimap_body_ext_mpart * body_ext_mpart; | 2967 | struct mailimap_body_ext_mpart * body_ext_mpart; |
2950 | int r; | 2968 | int r; |
2951 | int res; | 2969 | int res; |
2952 | 2970 | ||
2953 | cur_token = * index; | 2971 | cur_token = * index; |
2954 | 2972 | ||
2955 | body_list = NULL; | 2973 | body_list = NULL; |
2956 | media_subtype = NULL; | 2974 | media_subtype = NULL; |
2957 | body_ext_mpart = NULL; | 2975 | body_ext_mpart = NULL; |
2958 | 2976 | ||
2959 | r = mailimap_struct_multiple_parse(fd, buffer, &cur_token, | 2977 | r = mailimap_struct_multiple_parse(fd, buffer, &cur_token, |
2960 | &body_list, | 2978 | &body_list, |
2961 | (mailimap_struct_parser *) | 2979 | (mailimap_struct_parser *) |
2962 | mailimap_body_parse, | 2980 | mailimap_body_parse, |
2963 | (mailimap_struct_destructor *) | 2981 | (mailimap_struct_destructor *) |
2964 | mailimap_body_free, | 2982 | mailimap_body_free, |
2965 | progr_rate, progr_fun); | 2983 | progr_rate, progr_fun); |
2966 | if (r != MAILIMAP_NO_ERROR) { | 2984 | if (r != MAILIMAP_NO_ERROR) { |
2967 | res = r; | 2985 | res = r; |
2968 | goto err; | 2986 | goto err; |
2969 | } | 2987 | } |
2970 | 2988 | ||
2971 | r = mailimap_space_parse(fd, buffer, &cur_token); | 2989 | r = mailimap_space_parse(fd, buffer, &cur_token); |
2972 | if (r != MAILIMAP_NO_ERROR) { | 2990 | if (r != MAILIMAP_NO_ERROR) { |
2973 | res = r; | 2991 | res = r; |
2974 | goto free_body_list; | 2992 | goto free_body_list; |
2975 | } | 2993 | } |
2976 | 2994 | ||
2977 | r = mailimap_media_subtype_parse(fd, buffer, &cur_token, &media_subtype, | 2995 | r = mailimap_media_subtype_parse(fd, buffer, &cur_token, &media_subtype, |
2978 | progr_rate, progr_fun); | 2996 | progr_rate, progr_fun); |
2979 | if (r != MAILIMAP_NO_ERROR) { | 2997 | if (r != MAILIMAP_NO_ERROR) { |
2980 | res = r; | 2998 | res = r; |
2981 | goto free_body_list; | 2999 | goto free_body_list; |
2982 | } | 3000 | } |
2983 | 3001 | ||
2984 | final_token = cur_token; | 3002 | final_token = cur_token; |
2985 | 3003 | ||
2986 | body_ext_mpart = NULL; | 3004 | body_ext_mpart = NULL; |
2987 | 3005 | ||
2988 | r = mailimap_space_parse(fd, buffer, &cur_token); | 3006 | r = mailimap_space_parse(fd, buffer, &cur_token); |
2989 | if (r == MAILIMAP_NO_ERROR) { | 3007 | if (r == MAILIMAP_NO_ERROR) { |
2990 | r = mailimap_body_ext_mpart_parse(fd, buffer, &cur_token, &body_ext_mpart, | 3008 | r = mailimap_body_ext_mpart_parse(fd, buffer, &cur_token, &body_ext_mpart, |
2991 | progr_rate, progr_fun); | 3009 | progr_rate, progr_fun); |
2992 | if (r == MAILIMAP_NO_ERROR) | 3010 | if (r == MAILIMAP_NO_ERROR) |
2993 | final_token = cur_token; | 3011 | final_token = cur_token; |
2994 | else if (r == MAILIMAP_ERROR_PARSE) { | 3012 | else if (r == MAILIMAP_ERROR_PARSE) { |
2995 | /* do nothing */ | 3013 | /* do nothing */ |
2996 | } | 3014 | } |
2997 | else { | 3015 | else { |
2998 | res = r; | 3016 | res = r; |
2999 | goto free_body_list; | 3017 | goto free_body_list; |
3000 | } | 3018 | } |
3001 | } | 3019 | } |
3002 | else if (r == MAILIMAP_ERROR_PARSE) { | 3020 | else if (r == MAILIMAP_ERROR_PARSE) { |
3003 | /* do nothing */ | 3021 | /* do nothing */ |
3004 | } | 3022 | } |
3005 | else { | 3023 | else { |
3006 | res = r; | 3024 | res = r; |
3007 | goto free_body_list; | 3025 | goto free_body_list; |
3008 | } | 3026 | } |
3009 | 3027 | ||
3010 | body_type_mpart = mailimap_body_type_mpart_new(body_list, media_subtype, | 3028 | body_type_mpart = mailimap_body_type_mpart_new(body_list, media_subtype, |
3011 | body_ext_mpart); | 3029 | body_ext_mpart); |
3012 | if (body_type_mpart == NULL) { | 3030 | if (body_type_mpart == NULL) { |
3013 | res = MAILIMAP_ERROR_MEMORY; | 3031 | res = MAILIMAP_ERROR_MEMORY; |
3014 | goto free_body_ext_mpart; | 3032 | goto free_body_ext_mpart; |
3015 | } | 3033 | } |
3016 | 3034 | ||
3017 | * result = body_type_mpart; | 3035 | * result = body_type_mpart; |
3018 | * index = final_token; | 3036 | * index = final_token; |
3019 | 3037 | ||
3020 | return MAILIMAP_NO_ERROR; | 3038 | return MAILIMAP_NO_ERROR; |
3021 | 3039 | ||
3022 | free_body_ext_mpart: | 3040 | free_body_ext_mpart: |
3023 | if (body_ext_mpart) | 3041 | if (body_ext_mpart) |
3024 | mailimap_body_ext_mpart_free(body_ext_mpart); | 3042 | mailimap_body_ext_mpart_free(body_ext_mpart); |
3025 | mailimap_media_subtype_free(media_subtype); | 3043 | mailimap_media_subtype_free(media_subtype); |
3026 | free_body_list: | 3044 | free_body_list: |
3027 | clist_foreach(body_list, (clist_func) mailimap_body_free, NULL); | 3045 | clist_foreach(body_list, (clist_func) mailimap_body_free, NULL); |
3028 | clist_free(body_list); | 3046 | clist_free(body_list); |
3029 | err: | 3047 | err: |
3030 | return res; | 3048 | return res; |
3031 | } | 3049 | } |
3032 | 3050 | ||
3033 | /* | 3051 | /* |
3034 | body-type-msg = media-message SP body-fields SP envelope | 3052 | body-type-msg = media-message SP body-fields SP envelope |
3035 | SP body SP body-fld-lines | 3053 | SP body SP body-fld-lines |
3036 | */ | 3054 | */ |
3037 | 3055 | ||
3038 | static int | 3056 | static int |
3039 | mailimap_body_type_msg_parse(mailstream * fd, MMAPString * buffer, | 3057 | mailimap_body_type_msg_parse(mailstream * fd, MMAPString * buffer, |
3040 | size_t * index, | 3058 | size_t * index, |
3041 | struct mailimap_body_type_msg ** result, | 3059 | struct mailimap_body_type_msg ** result, |
3042 | size_t progr_rate, | 3060 | size_t progr_rate, |
3043 | progress_function * progr_fun) | 3061 | progress_function * progr_fun) |
3044 | { | 3062 | { |
3045 | struct mailimap_body_fields * body_fields; | 3063 | struct mailimap_body_fields * body_fields; |
3046 | struct mailimap_envelope * envelope; | 3064 | struct mailimap_envelope * envelope; |
3047 | struct mailimap_body * body; | 3065 | struct mailimap_body * body; |
3048 | uint32_t body_fld_lines; | 3066 | uint32_t body_fld_lines; |
3049 | struct mailimap_body_type_msg * body_type_msg; | 3067 | struct mailimap_body_type_msg * body_type_msg; |
3050 | size_t cur_token; | 3068 | size_t cur_token; |
3051 | int r; | 3069 | int r; |
3052 | int res; | 3070 | int res; |
3053 | 3071 | ||
3054 | cur_token = * index; | 3072 | cur_token = * index; |
3055 | 3073 | ||
3056 | body_fields = NULL; | 3074 | body_fields = NULL; |
3057 | envelope = NULL; | 3075 | envelope = NULL; |
3058 | body = NULL; | 3076 | body = NULL; |
3059 | body_fld_lines = 0; | 3077 | body_fld_lines = 0; |
3060 | 3078 | ||
3061 | r = mailimap_media_message_parse(fd, buffer, &cur_token); | 3079 | r = mailimap_media_message_parse(fd, buffer, &cur_token); |
3062 | if (r != MAILIMAP_NO_ERROR) { | 3080 | if (r != MAILIMAP_NO_ERROR) { |
3063 | res = r; | 3081 | res = r; |
3064 | goto err; | 3082 | goto err; |
3065 | } | 3083 | } |
3066 | 3084 | ||
3067 | r = mailimap_space_parse(fd, buffer, &cur_token); | 3085 | r = mailimap_space_parse(fd, buffer, &cur_token); |
3068 | if (r != MAILIMAP_NO_ERROR) { | 3086 | if (r != MAILIMAP_NO_ERROR) { |
3069 | res = r; | 3087 | res = r; |
3070 | goto err; | 3088 | goto err; |
3071 | } | 3089 | } |
3072 | 3090 | ||
3073 | r = mailimap_body_fields_parse(fd, buffer, &cur_token, &body_fields, | 3091 | r = mailimap_body_fields_parse(fd, buffer, &cur_token, &body_fields, |
3074 | progr_rate, progr_fun); | 3092 | progr_rate, progr_fun); |
3075 | if (r != MAILIMAP_NO_ERROR) { | 3093 | if (r != MAILIMAP_NO_ERROR) { |
3076 | res = r; | 3094 | res = r; |
3077 | goto err; | 3095 | goto err; |
3078 | } | 3096 | } |
3079 | 3097 | ||
3080 | r = mailimap_space_parse(fd, buffer, &cur_token); | 3098 | r = mailimap_space_parse(fd, buffer, &cur_token); |
3081 | if (r != MAILIMAP_NO_ERROR) { | 3099 | if (r != MAILIMAP_NO_ERROR) { |
3082 | res = r; | 3100 | res = r; |
3083 | goto body_fields; | 3101 | goto body_fields; |
3084 | } | 3102 | } |
3085 | 3103 | ||
3086 | r = mailimap_envelope_parse(fd, buffer, &cur_token, &envelope, | 3104 | r = mailimap_envelope_parse(fd, buffer, &cur_token, &envelope, |
3087 | progr_rate, progr_fun); | 3105 | progr_rate, progr_fun); |
3088 | if (r != MAILIMAP_NO_ERROR) { | 3106 | if (r != MAILIMAP_NO_ERROR) { |
3089 | res = r; | 3107 | res = r; |
3090 | goto body_fields; | 3108 | goto body_fields; |
3091 | } | 3109 | } |
3092 | 3110 | ||
3093 | r = mailimap_space_parse(fd, buffer, &cur_token); | 3111 | r = mailimap_space_parse(fd, buffer, &cur_token); |
3094 | if (r != MAILIMAP_NO_ERROR) { | 3112 | if (r != MAILIMAP_NO_ERROR) { |
3095 | res = r; | 3113 | res = r; |
3096 | goto envelope; | 3114 | goto envelope; |
3097 | } | 3115 | } |
3098 | 3116 | ||
3099 | r = mailimap_body_parse(fd, buffer, &cur_token, &body, | 3117 | r = mailimap_body_parse(fd, buffer, &cur_token, &body, |
3100 | progr_rate, progr_fun); | 3118 | progr_rate, progr_fun); |
3101 | if (r != MAILIMAP_NO_ERROR) { | 3119 | if (r != MAILIMAP_NO_ERROR) { |
3102 | res = r; | 3120 | res = r; |
3103 | goto envelope; | 3121 | goto envelope; |
3104 | } | 3122 | } |
3105 | 3123 | ||
3106 | r = mailimap_space_parse(fd, buffer, &cur_token); | 3124 | r = mailimap_space_parse(fd, buffer, &cur_token); |
3107 | if (r != MAILIMAP_NO_ERROR) { | 3125 | if (r != MAILIMAP_NO_ERROR) { |
3108 | res = r; | 3126 | res = r; |
3109 | goto body; | 3127 | goto body; |
3110 | } | 3128 | } |
3111 | 3129 | ||
3112 | r = mailimap_body_fld_lines_parse(fd, buffer, &cur_token, | 3130 | r = mailimap_body_fld_lines_parse(fd, buffer, &cur_token, |
3113 | &body_fld_lines); | 3131 | &body_fld_lines); |
3114 | if (r != MAILIMAP_NO_ERROR) { | 3132 | if (r != MAILIMAP_NO_ERROR) { |
3115 | res = r; | 3133 | res = r; |
3116 | goto body; | 3134 | goto body; |
3117 | } | 3135 | } |
3118 | 3136 | ||
3119 | body_type_msg = mailimap_body_type_msg_new(body_fields, envelope, | 3137 | body_type_msg = mailimap_body_type_msg_new(body_fields, envelope, |
3120 | body, body_fld_lines); | 3138 | body, body_fld_lines); |
3121 | if (body_type_msg == NULL) { | 3139 | if (body_type_msg == NULL) { |
3122 | res = MAILIMAP_ERROR_MEMORY; | 3140 | res = MAILIMAP_ERROR_MEMORY; |
3123 | goto body; | 3141 | goto body; |
3124 | } | 3142 | } |
3125 | 3143 | ||
3126 | * result = body_type_msg; | 3144 | * result = body_type_msg; |
3127 | * index = cur_token; | 3145 | * index = cur_token; |
3128 | 3146 | ||
3129 | return MAILIMAP_NO_ERROR; | 3147 | return MAILIMAP_NO_ERROR; |
3130 | 3148 | ||
3131 | body: | 3149 | body: |
3132 | mailimap_body_free(body); | 3150 | mailimap_body_free(body); |
3133 | envelope: | 3151 | envelope: |
3134 | mailimap_envelope_free(envelope); | 3152 | mailimap_envelope_free(envelope); |
3135 | body_fields: | 3153 | body_fields: |
3136 | mailimap_body_fields_free(body_fields); | 3154 | mailimap_body_fields_free(body_fields); |
3137 | err: | 3155 | err: |
3138 | return res; | 3156 | return res; |
3139 | } | 3157 | } |
3140 | 3158 | ||
3141 | /* | 3159 | /* |
3142 | body-type-text = media-text SP body-fields SP body-fld-lines | 3160 | body-type-text = media-text SP body-fields SP body-fld-lines |
3143 | */ | 3161 | */ |
3144 | 3162 | ||
3145 | static int | 3163 | static int |
3146 | mailimap_body_type_text_parse(mailstream * fd, MMAPString * buffer, | 3164 | mailimap_body_type_text_parse(mailstream * fd, MMAPString * buffer, |
3147 | size_t * index, | 3165 | size_t * index, |
3148 | struct mailimap_body_type_text ** | 3166 | struct mailimap_body_type_text ** |
3149 | result, | 3167 | result, |
3150 | size_t progr_rate, | 3168 | size_t progr_rate, |
3151 | progress_function * progr_fun) | 3169 | progress_function * progr_fun) |
3152 | { | 3170 | { |
3153 | char * media_text; | 3171 | char * media_text; |
3154 | struct mailimap_body_fields * body_fields; | 3172 | struct mailimap_body_fields * body_fields; |
3155 | uint32_t body_fld_lines; | 3173 | uint32_t body_fld_lines; |
3156 | struct mailimap_body_type_text * body_type_text; | 3174 | struct mailimap_body_type_text * body_type_text; |
3157 | size_t cur_token; | 3175 | size_t cur_token; |
3158 | int r; | 3176 | int r; |
3159 | int res; | 3177 | int res; |
3160 | 3178 | ||
3161 | media_text = NULL; | 3179 | media_text = NULL; |
3162 | body_fields = NULL; | 3180 | body_fields = NULL; |
3163 | body_fld_lines = 0; | 3181 | body_fld_lines = 0; |
3164 | 3182 | ||
3165 | cur_token = * index; | 3183 | cur_token = * index; |
3166 | 3184 | ||
3167 | r = mailimap_media_text_parse(fd, buffer, &cur_token, &media_text, | 3185 | r = mailimap_media_text_parse(fd, buffer, &cur_token, &media_text, |
3168 | progr_rate, progr_fun); | 3186 | progr_rate, progr_fun); |
3169 | if (r != MAILIMAP_NO_ERROR) { | 3187 | if (r != MAILIMAP_NO_ERROR) { |
3170 | res = r; | 3188 | res = r; |
3171 | goto err; | 3189 | goto err; |
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,798 +1,811 @@ | |||
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; |
343 | } | 356 | } |
344 | 357 | ||
345 | while ((entry = readdir(d)) != NULL) { | 358 | while ((entry = readdir(d)) != NULL) { |
346 | #if 0 | 359 | #if 0 |
347 | struct stat stat_info; | 360 | struct stat stat_info; |
348 | 361 | ||
349 | snprintf(filename, sizeof(filename), "%s/%s", path, entry->d_name); | 362 | snprintf(filename, sizeof(filename), "%s/%s", path, entry->d_name); |
350 | 363 | ||
351 | r = stat(filename, &stat_info); | 364 | r = stat(filename, &stat_info); |
352 | if (r < 0) | 365 | if (r < 0) |
353 | continue; | 366 | continue; |
354 | 367 | ||
355 | if (S_ISDIR(stat_info.st_mode)) | 368 | if (S_ISDIR(stat_info.st_mode)) |
356 | continue; | 369 | continue; |
357 | #endif | 370 | #endif |
358 | 371 | ||
359 | if (entry->d_name[0] == '.') | 372 | if (entry->d_name[0] == '.') |
360 | continue; | 373 | continue; |
361 | 374 | ||
362 | r = add_message(md, entry->d_name, is_new); | 375 | r = add_message(md, entry->d_name, is_new); |
363 | if (r != MAILDIR_NO_ERROR) { | 376 | if (r != MAILDIR_NO_ERROR) { |
364 | /* ignore errors */ | 377 | /* ignore errors */ |
365 | } | 378 | } |
366 | } | 379 | } |
367 | 380 | ||
368 | closedir(d); | 381 | closedir(d); |
369 | 382 | ||
370 | return MAILDIR_NO_ERROR; | 383 | return MAILDIR_NO_ERROR; |
371 | 384 | ||
372 | err: | 385 | err: |
373 | return res; | 386 | return res; |
374 | } | 387 | } |
375 | 388 | ||
376 | int maildir_update(struct maildir * md) | 389 | int maildir_update(struct maildir * md) |
377 | { | 390 | { |
378 | struct stat stat_info; | 391 | struct stat stat_info; |
379 | char path_new[PATH_MAX]; | 392 | char path_new[PATH_MAX]; |
380 | char path_cur[PATH_MAX]; | 393 | char path_cur[PATH_MAX]; |
381 | char path_maildirfolder[PATH_MAX]; | 394 | char path_maildirfolder[PATH_MAX]; |
382 | int r; | 395 | int r; |
383 | int res; | 396 | int res; |
384 | int changed; | 397 | int changed; |
385 | 398 | ||
386 | snprintf(path_new, sizeof(path_new), "%s/new", md->mdir_path); | 399 | snprintf(path_new, sizeof(path_new), "%s/new", md->mdir_path); |
387 | snprintf(path_cur, sizeof(path_cur), "%s/cur", md->mdir_path); | 400 | snprintf(path_cur, sizeof(path_cur), "%s/cur", md->mdir_path); |
388 | 401 | ||
389 | changed = 0; | 402 | changed = 0; |
390 | 403 | ||
391 | /* did new/ changed ? */ | 404 | /* did new/ changed ? */ |
392 | 405 | ||
393 | r = stat(path_new, &stat_info); | 406 | r = stat(path_new, &stat_info); |
394 | if (r < 0) { | 407 | if (r < 0) { |
395 | res = MAILDIR_ERROR_DIRECTORY; | 408 | res = MAILDIR_ERROR_DIRECTORY; |
396 | goto free; | 409 | goto free; |
397 | } | 410 | } |
398 | 411 | ||
399 | if (md->mdir_mtime_new != stat_info.st_mtime) { | 412 | if (md->mdir_mtime_new != stat_info.st_mtime) { |
400 | md->mdir_mtime_new = stat_info.st_mtime; | 413 | md->mdir_mtime_new = stat_info.st_mtime; |
401 | changed = 1; | 414 | changed = 1; |
402 | } | 415 | } |
403 | 416 | ||
404 | /* did cur/ changed ? */ | 417 | /* did cur/ changed ? */ |
405 | 418 | ||
406 | r = stat(path_cur, &stat_info); | 419 | r = stat(path_cur, &stat_info); |
407 | if (r < 0) { | 420 | if (r < 0) { |
408 | res = MAILDIR_ERROR_DIRECTORY; | 421 | res = MAILDIR_ERROR_DIRECTORY; |
409 | goto free; | 422 | goto free; |
410 | } | 423 | } |
411 | 424 | ||
412 | if (md->mdir_mtime_cur != stat_info.st_mtime) { | 425 | if (md->mdir_mtime_cur != stat_info.st_mtime) { |
413 | md->mdir_mtime_cur = stat_info.st_mtime; | 426 | md->mdir_mtime_cur = stat_info.st_mtime; |
414 | changed = 1; | 427 | changed = 1; |
415 | } | 428 | } |
416 | 429 | ||
417 | if (changed) { | 430 | if (changed) { |
418 | 431 | ||
419 | carray_set_size(md->mdir_msg_list, 0); | 432 | carray_set_size(md->mdir_msg_list, 0); |
420 | chash_clear(md->mdir_msg_hash); | 433 | chash_clear(md->mdir_msg_hash); |
421 | 434 | ||
422 | maildir_flush(md, 1); | 435 | maildir_flush(md, 1); |
423 | 436 | ||
424 | /* messages in new */ | 437 | /* messages in new */ |
425 | r = add_directory(md, path_new, 1); | 438 | r = add_directory(md, path_new, 1); |
426 | if (r != MAILDIR_NO_ERROR) { | 439 | if (r != MAILDIR_NO_ERROR) { |
427 | res = r; | 440 | res = r; |
428 | goto free; | 441 | goto free; |
429 | } | 442 | } |
430 | 443 | ||
431 | maildir_flush(md, 0); | 444 | maildir_flush(md, 0); |
432 | 445 | ||
433 | /* messages in cur */ | 446 | /* messages in cur */ |
434 | r = add_directory(md, path_cur, 0); | 447 | r = add_directory(md, path_cur, 0); |
435 | if (r != MAILDIR_NO_ERROR) { | 448 | if (r != MAILDIR_NO_ERROR) { |
436 | res = r; | 449 | res = r; |
437 | goto free; | 450 | goto free; |
438 | } | 451 | } |
439 | } | 452 | } |
440 | 453 | ||
441 | snprintf(path_maildirfolder, sizeof(path_maildirfolder), | 454 | snprintf(path_maildirfolder, sizeof(path_maildirfolder), |
442 | "%s/maildirfolder", md->mdir_path); | 455 | "%s/maildirfolder", md->mdir_path); |
443 | 456 | ||
444 | if (stat(path_maildirfolder, &stat_info) == -1) { | 457 | if (stat(path_maildirfolder, &stat_info) == -1) { |
445 | int fd; | 458 | int fd; |
446 | 459 | ||
447 | fd = creat(path_maildirfolder, S_IRUSR | S_IWUSR); | 460 | fd = creat(path_maildirfolder, S_IRUSR | S_IWUSR); |
448 | if (fd != -1) | 461 | if (fd != -1) |
449 | close(fd); | 462 | close(fd); |
450 | } | 463 | } |
451 | 464 | ||
452 | return MAILDIR_NO_ERROR; | 465 | return MAILDIR_NO_ERROR; |
453 | 466 | ||
454 | free: | 467 | free: |
455 | maildir_flush(md, 0); | 468 | maildir_flush(md, 0); |
456 | maildir_flush(md, 1); | 469 | maildir_flush(md, 1); |
457 | md->mdir_mtime_cur = (time_t) -1; | 470 | md->mdir_mtime_cur = (time_t) -1; |
458 | md->mdir_mtime_new = (time_t) -1; | 471 | md->mdir_mtime_new = (time_t) -1; |
459 | return res; | 472 | return res; |
460 | } | 473 | } |
461 | 474 | ||
462 | #ifndef LIBETPAN_SYSTEM_BASENAME | 475 | #ifndef LIBETPAN_SYSTEM_BASENAME |
463 | static char * libetpan_basename(char * filename) | 476 | static char * libetpan_basename(char * filename) |
464 | { | 477 | { |
465 | char * next; | 478 | char * next; |
466 | char * p; | 479 | char * p; |
467 | 480 | ||
468 | p = filename; | 481 | p = filename; |
469 | next = strchr(p, '/'); | 482 | next = strchr(p, '/'); |
470 | 483 | ||
471 | while (next != NULL) { | 484 | while (next != NULL) { |
472 | p = next; | 485 | p = next; |
473 | next = strchr(p + 1, '/'); | 486 | next = strchr(p + 1, '/'); |
474 | } | 487 | } |
475 | 488 | ||
476 | if (p == filename) | 489 | if (p == filename) |
477 | return filename; | 490 | return filename; |
478 | else | 491 | else |
479 | return p + 1; | 492 | return p + 1; |
480 | } | 493 | } |
481 | #else | 494 | #else |
482 | #define libetpan_basename(a) basename(a) | 495 | #define libetpan_basename(a) basename(a) |
483 | #endif | 496 | #endif |
484 | 497 | ||
485 | int maildir_message_add_uid(struct maildir * md, | 498 | int maildir_message_add_uid(struct maildir * md, |
486 | const char * message, size_t size, | 499 | const char * message, size_t size, |
487 | char * uid, size_t max_uid_len) | 500 | char * uid, size_t max_uid_len) |
488 | { | 501 | { |
489 | char path_new[PATH_MAX]; | 502 | char path_new[PATH_MAX]; |
490 | char tmpname[PATH_MAX]; | 503 | char tmpname[PATH_MAX]; |
491 | int fd; | 504 | int fd; |
492 | int r; | 505 | int r; |
493 | char * mapping; | 506 | char * mapping; |
494 | char * delivery_tmp_name; | 507 | char * delivery_tmp_name; |
495 | char * delivery_tmp_basename; | 508 | char * delivery_tmp_basename; |
496 | char delivery_new_name[PATH_MAX]; | 509 | char delivery_new_name[PATH_MAX]; |
497 | char * delivery_new_basename; | 510 | char * delivery_new_basename; |
498 | int res; | 511 | int res; |
499 | struct stat stat_info; | 512 | struct stat stat_info; |
500 | 513 | ||
501 | r = maildir_update(md); | 514 | r = maildir_update(md); |
502 | if (r != MAILDIR_NO_ERROR) { | 515 | if (r != MAILDIR_NO_ERROR) { |
503 | res = r; | 516 | res = r; |
504 | goto err; | 517 | goto err; |
505 | } | 518 | } |
506 | 519 | ||
507 | /* write to tmp/ with a classic temporary file */ | 520 | /* write to tmp/ with a classic temporary file */ |
508 | 521 | ||
509 | snprintf(tmpname, sizeof(tmpname), "%s/tmp/etpan-maildir-XXXXXX", | 522 | snprintf(tmpname, sizeof(tmpname), "%s/tmp/etpan-maildir-XXXXXX", |
510 | md->mdir_path); | 523 | md->mdir_path); |
511 | fd = mkstemp(tmpname); | 524 | fd = mkstemp(tmpname); |
512 | if (fd < 0) { | 525 | if (fd < 0) { |
513 | res = MAILDIR_ERROR_FILE; | 526 | res = MAILDIR_ERROR_FILE; |
514 | goto err; | 527 | goto err; |
515 | } | 528 | } |
516 | 529 | ||
517 | r = ftruncate(fd, size); | 530 | r = ftruncate(fd, size); |
518 | if (r < 0) { | 531 | if (r < 0) { |
519 | res = MAILDIR_ERROR_FILE; | 532 | res = MAILDIR_ERROR_FILE; |
520 | goto close; | 533 | goto close; |
521 | } | 534 | } |
522 | 535 | ||
523 | mapping = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | 536 | mapping = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); |
524 | if (mapping == MAP_FAILED) { | 537 | if (mapping == MAP_FAILED) { |
525 | res = MAILDIR_ERROR_FILE; | 538 | res = MAILDIR_ERROR_FILE; |
526 | goto close; | 539 | goto close; |
527 | } | 540 | } |
528 | 541 | ||
529 | memcpy(mapping, message, size); | 542 | memcpy(mapping, message, size); |
530 | 543 | ||
531 | msync(mapping, size, MS_SYNC); | 544 | msync(mapping, size, MS_SYNC); |
532 | munmap(mapping, size); | 545 | munmap(mapping, size); |
533 | 546 | ||
534 | close(fd); | 547 | close(fd); |
535 | 548 | ||
536 | /* write to tmp/ with maildir standard name */ | 549 | /* write to tmp/ with maildir standard name */ |
537 | 550 | ||
538 | delivery_tmp_name = maildir_get_new_message_filename(md, tmpname); | 551 | delivery_tmp_name = maildir_get_new_message_filename(md, tmpname); |
539 | if (delivery_tmp_name == NULL) { | 552 | if (delivery_tmp_name == NULL) { |
540 | res = MAILDIR_ERROR_FILE; | 553 | res = MAILDIR_ERROR_FILE; |
541 | goto unlink; | 554 | goto unlink; |
542 | } | 555 | } |
543 | 556 | ||
544 | /* write to new/ with maildir standard name */ | 557 | /* write to new/ with maildir standard name */ |
545 | 558 | ||
546 | strncpy(tmpname, delivery_tmp_name, sizeof(tmpname)); | 559 | strncpy(tmpname, delivery_tmp_name, sizeof(tmpname)); |
547 | tmpname[sizeof(tmpname) - 1] = '\0'; | 560 | tmpname[sizeof(tmpname) - 1] = '\0'; |
548 | 561 | ||
549 | delivery_tmp_basename = libetpan_basename(tmpname); | 562 | delivery_tmp_basename = libetpan_basename(tmpname); |
550 | 563 | ||
551 | snprintf(delivery_new_name, sizeof(delivery_new_name), "%s/new/%s", | 564 | snprintf(delivery_new_name, sizeof(delivery_new_name), "%s/new/%s", |
552 | md->mdir_path, delivery_tmp_basename); | 565 | md->mdir_path, delivery_tmp_basename); |
553 | 566 | ||
554 | r = link(delivery_tmp_name, delivery_new_name); | 567 | r = link(delivery_tmp_name, delivery_new_name); |
555 | if (r == 0) { | 568 | if (r == 0) { |
556 | unlink(delivery_tmp_name); | 569 | unlink(delivery_tmp_name); |
557 | } | 570 | } |
558 | else if (errno == EXDEV) { | 571 | else if (errno == EXDEV) { |
559 | res = MAILDIR_ERROR_FOLDER; | 572 | res = MAILDIR_ERROR_FOLDER; |
560 | goto unlink_tmp; | 573 | goto unlink_tmp; |
561 | } | 574 | } |
562 | else if (errno == EPERM) { | 575 | else if (errno == EPERM) { |
563 | r = rename(delivery_tmp_name, delivery_new_name); | 576 | r = rename(delivery_tmp_name, delivery_new_name); |
564 | if (r < 0) { | 577 | if (r < 0) { |
565 | res = MAILDIR_ERROR_FILE; | 578 | res = MAILDIR_ERROR_FILE; |
566 | goto unlink_tmp; | 579 | goto unlink_tmp; |
567 | } | 580 | } |
568 | } | 581 | } |
569 | 582 | ||
570 | snprintf(path_new, sizeof(path_new), "%s/new", md->mdir_path); | 583 | snprintf(path_new, sizeof(path_new), "%s/new", md->mdir_path); |
571 | r = stat(path_new, &stat_info); | 584 | r = stat(path_new, &stat_info); |
572 | if (r < 0) { | 585 | if (r < 0) { |
573 | unlink(delivery_new_name); | 586 | unlink(delivery_new_name); |
574 | res = MAILDIR_ERROR_FILE; | 587 | res = MAILDIR_ERROR_FILE; |
575 | goto unlink_tmp; | 588 | goto unlink_tmp; |
576 | } | 589 | } |
577 | 590 | ||
578 | md->mdir_mtime_new = stat_info.st_mtime; | 591 | md->mdir_mtime_new = stat_info.st_mtime; |
579 | 592 | ||
580 | delivery_new_basename = libetpan_basename(delivery_new_name); | 593 | delivery_new_basename = libetpan_basename(delivery_new_name); |
581 | 594 | ||
582 | r = add_message(md, delivery_new_basename, 1); | 595 | r = add_message(md, delivery_new_basename, 1); |
583 | if (r != MAILDIR_NO_ERROR) { | 596 | if (r != MAILDIR_NO_ERROR) { |
584 | unlink(delivery_new_name); | 597 | unlink(delivery_new_name); |
585 | res = MAILDIR_ERROR_FILE; | 598 | res = MAILDIR_ERROR_FILE; |
586 | goto unlink_tmp; | 599 | goto unlink_tmp; |
587 | } | 600 | } |
588 | 601 | ||
589 | if (uid != NULL) | 602 | if (uid != NULL) |
590 | strncpy(uid, delivery_new_basename, max_uid_len); | 603 | strncpy(uid, delivery_new_basename, max_uid_len); |
591 | 604 | ||
592 | free(delivery_tmp_name); | 605 | free(delivery_tmp_name); |
593 | 606 | ||
594 | return MAILDIR_NO_ERROR; | 607 | return MAILDIR_NO_ERROR; |
595 | 608 | ||
596 | unlink_tmp: | 609 | unlink_tmp: |
597 | unlink(delivery_tmp_name); | 610 | unlink(delivery_tmp_name); |
598 | free(delivery_tmp_name); | 611 | free(delivery_tmp_name); |
599 | goto err; | 612 | goto err; |
600 | close: | 613 | close: |
601 | close(fd); | 614 | close(fd); |
602 | unlink: | 615 | unlink: |
603 | unlink(tmpname); | 616 | unlink(tmpname); |
604 | err: | 617 | err: |
605 | return res; | 618 | return res; |
606 | } | 619 | } |
607 | 620 | ||
608 | int maildir_message_add(struct maildir * md, | 621 | int maildir_message_add(struct maildir * md, |
609 | const char * message, size_t size) | 622 | const char * message, size_t size) |
610 | { | 623 | { |
611 | return maildir_message_add_uid(md, message, size, | 624 | return maildir_message_add_uid(md, message, size, |
612 | NULL, 0); | 625 | NULL, 0); |
613 | } | 626 | } |
614 | 627 | ||
615 | int maildir_message_add_file_uid(struct maildir * md, int fd, | 628 | int maildir_message_add_file_uid(struct maildir * md, int fd, |
616 | char * uid, size_t max_uid_len) | 629 | char * uid, size_t max_uid_len) |
617 | { | 630 | { |
618 | char * message; | 631 | char * message; |
619 | struct stat buf; | 632 | struct stat buf; |
620 | int r; | 633 | int r; |
621 | 634 | ||
622 | if (fstat(fd, &buf) == -1) | 635 | if (fstat(fd, &buf) == -1) |
623 | return MAILDIR_ERROR_FILE; | 636 | return MAILDIR_ERROR_FILE; |
624 | 637 | ||
625 | message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | 638 | message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); |
626 | if (message == MAP_FAILED) | 639 | if (message == MAP_FAILED) |
627 | return MAILDIR_ERROR_FILE; | 640 | return MAILDIR_ERROR_FILE; |
628 | 641 | ||
629 | r = maildir_message_add_uid(md, message, buf.st_size, uid, max_uid_len); | 642 | r = maildir_message_add_uid(md, message, buf.st_size, uid, max_uid_len); |
630 | 643 | ||
631 | munmap(message, buf.st_size); | 644 | munmap(message, buf.st_size); |
632 | 645 | ||
633 | return r; | 646 | return r; |
634 | } | 647 | } |
635 | 648 | ||
636 | int maildir_message_add_file(struct maildir * md, int fd) | 649 | int maildir_message_add_file(struct maildir * md, int fd) |
637 | { | 650 | { |
638 | return maildir_message_add_file_uid(md, fd, | 651 | return maildir_message_add_file_uid(md, fd, |
639 | NULL, 0); | 652 | NULL, 0); |
640 | } | 653 | } |
641 | 654 | ||
642 | char * maildir_message_get(struct maildir * md, const char * uid) | 655 | char * maildir_message_get(struct maildir * md, const char * uid) |
643 | { | 656 | { |
644 | chashdatum key; | 657 | chashdatum key; |
645 | chashdatum value; | 658 | chashdatum value; |
646 | char filename[PATH_MAX]; | 659 | char filename[PATH_MAX]; |
647 | char * dup_filename; | 660 | char * dup_filename; |
648 | struct maildir_msg * msg; | 661 | struct maildir_msg * msg; |
649 | char * dir; | 662 | char * dir; |
650 | int r; | 663 | int r; |
651 | 664 | ||
652 | key.data = (void *) uid; | 665 | key.data = (void *) uid; |
653 | key.len = strlen(uid); | 666 | key.len = strlen(uid); |
654 | r = chash_get(md->mdir_msg_hash, &key, &value); | 667 | r = chash_get(md->mdir_msg_hash, &key, &value); |
655 | if (r < 0) | 668 | if (r < 0) |
656 | return NULL; | 669 | return NULL; |
657 | 670 | ||
658 | msg = value.data; | 671 | msg = value.data; |
659 | if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) | 672 | if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) |
660 | dir = "new"; | 673 | dir = "new"; |
661 | else | 674 | else |
662 | dir = "cur"; | 675 | dir = "cur"; |
663 | 676 | ||
664 | snprintf(filename, sizeof(filename), "%s/%s/%s", | 677 | snprintf(filename, sizeof(filename), "%s/%s/%s", |
665 | md->mdir_path, dir, msg->msg_filename); | 678 | md->mdir_path, dir, msg->msg_filename); |
666 | 679 | ||
667 | dup_filename = strdup(filename); | 680 | dup_filename = strdup(filename); |
668 | if (dup_filename == NULL) | 681 | if (dup_filename == NULL) |
669 | return NULL; | 682 | return NULL; |
670 | 683 | ||
671 | return dup_filename; | 684 | return dup_filename; |
672 | } | 685 | } |
673 | 686 | ||
674 | int maildir_message_remove(struct maildir * md, const char * uid) | 687 | int maildir_message_remove(struct maildir * md, const char * uid) |
675 | { | 688 | { |
676 | chashdatum key; | 689 | chashdatum key; |
677 | chashdatum value; | 690 | chashdatum value; |
678 | char filename[PATH_MAX]; | 691 | char filename[PATH_MAX]; |
679 | struct maildir_msg * msg; | 692 | struct maildir_msg * msg; |
680 | char * dir; | 693 | char * dir; |
681 | int r; | 694 | int r; |
682 | int res; | 695 | int res; |
683 | 696 | ||
684 | key.data = (void *) uid; | 697 | key.data = (void *) uid; |
685 | key.len = strlen(uid); | 698 | key.len = strlen(uid); |
686 | r = chash_get(md->mdir_msg_hash, &key, &value); | 699 | r = chash_get(md->mdir_msg_hash, &key, &value); |
687 | if (r < 0) { | 700 | if (r < 0) { |
688 | res = MAILDIR_ERROR_NOT_FOUND; | 701 | res = MAILDIR_ERROR_NOT_FOUND; |
689 | goto err; | 702 | goto err; |
690 | } | 703 | } |
691 | 704 | ||
692 | msg = value.data; | 705 | msg = value.data; |
693 | if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) | 706 | if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) |
694 | dir = "new"; | 707 | dir = "new"; |
695 | else | 708 | else |
696 | dir = "cur"; | 709 | dir = "cur"; |
697 | 710 | ||
698 | snprintf(filename, sizeof(filename), "%s/%s/%s", | 711 | snprintf(filename, sizeof(filename), "%s/%s/%s", |
699 | md->mdir_path, dir, msg->msg_filename); | 712 | md->mdir_path, dir, msg->msg_filename); |
700 | 713 | ||
701 | r = unlink(filename); | 714 | r = unlink(filename); |
702 | if (r < 0) { | 715 | if (r < 0) { |
703 | res = MAILDIR_ERROR_FILE; | 716 | res = MAILDIR_ERROR_FILE; |
704 | goto err; | 717 | goto err; |
705 | } | 718 | } |
706 | 719 | ||
707 | return MAILDIR_NO_ERROR; | 720 | return MAILDIR_NO_ERROR; |
708 | 721 | ||
709 | err: | 722 | err: |
710 | return res; | 723 | return res; |
711 | } | 724 | } |
712 | 725 | ||
713 | int maildir_message_change_flags(struct maildir * md, | 726 | int maildir_message_change_flags(struct maildir * md, |
714 | const char * uid, int new_flags) | 727 | const char * uid, int new_flags) |
715 | { | 728 | { |
716 | chashdatum key; | 729 | chashdatum key; |
717 | chashdatum value; | 730 | chashdatum value; |
718 | char filename[PATH_MAX]; | 731 | char filename[PATH_MAX]; |
719 | struct maildir_msg * msg; | 732 | struct maildir_msg * msg; |
720 | char * dir; | 733 | char * dir; |
721 | int r; | 734 | int r; |
722 | char new_filename[PATH_MAX]; | 735 | char new_filename[PATH_MAX]; |
723 | char flag_str[5]; | 736 | char flag_str[5]; |
724 | size_t i; | 737 | size_t i; |
725 | int res; | 738 | int res; |
726 | 739 | ||
727 | key.data = (void *) uid; | 740 | key.data = (void *) uid; |
728 | key.len = strlen(uid); | 741 | key.len = strlen(uid); |
729 | r = chash_get(md->mdir_msg_hash, &key, &value); | 742 | r = chash_get(md->mdir_msg_hash, &key, &value); |
730 | if (r < 0) { | 743 | if (r < 0) { |
731 | res = MAILDIR_ERROR_NOT_FOUND; | 744 | res = MAILDIR_ERROR_NOT_FOUND; |
732 | goto err; | 745 | goto err; |
733 | } | 746 | } |
734 | 747 | ||
735 | msg = value.data; | 748 | msg = value.data; |
736 | if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) | 749 | if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) |
737 | dir = "new"; | 750 | dir = "new"; |
738 | else | 751 | else |
739 | dir = "cur"; | 752 | dir = "cur"; |
740 | 753 | ||
741 | snprintf(filename, sizeof(filename), "%s/%s/%s", | 754 | snprintf(filename, sizeof(filename), "%s/%s/%s", |
742 | md->mdir_path, dir, msg->msg_filename); | 755 | md->mdir_path, dir, msg->msg_filename); |
743 | 756 | ||
744 | if ((new_flags & MAILDIR_FLAG_NEW) != 0) | 757 | if ((new_flags & MAILDIR_FLAG_NEW) != 0) |
745 | dir = "new"; | 758 | dir = "new"; |
746 | else | 759 | else |
747 | dir = "cur"; | 760 | dir = "cur"; |
748 | 761 | ||
749 | i = 0; | 762 | i = 0; |
750 | if ((new_flags & MAILDIR_FLAG_SEEN) != 0) { | 763 | if ((new_flags & MAILDIR_FLAG_SEEN) != 0) { |
751 | flag_str[i] = 'S'; | 764 | flag_str[i] = 'S'; |
752 | i ++; | 765 | i ++; |
753 | } | 766 | } |
754 | if ((new_flags & MAILDIR_FLAG_REPLIED) != 0) { | 767 | if ((new_flags & MAILDIR_FLAG_REPLIED) != 0) { |
755 | flag_str[i] = 'R'; | 768 | flag_str[i] = 'R'; |
756 | i ++; | 769 | i ++; |
757 | } | 770 | } |
758 | if ((new_flags & MAILDIR_FLAG_FLAGGED) != 0) { | 771 | if ((new_flags & MAILDIR_FLAG_FLAGGED) != 0) { |
759 | flag_str[i] = 'F'; | 772 | flag_str[i] = 'F'; |
760 | i ++; | 773 | i ++; |
761 | } | 774 | } |
762 | if ((new_flags & MAILDIR_FLAG_TRASHED) != 0) { | 775 | if ((new_flags & MAILDIR_FLAG_TRASHED) != 0) { |
763 | flag_str[i] = 'T'; | 776 | flag_str[i] = 'T'; |
764 | i ++; | 777 | i ++; |
765 | } | 778 | } |
766 | flag_str[i] = 0; | 779 | flag_str[i] = 0; |
767 | 780 | ||
768 | if (flag_str[0] == '\0') | 781 | if (flag_str[0] == '\0') |
769 | snprintf(new_filename, sizeof(new_filename), "%s/%s/%s", | 782 | snprintf(new_filename, sizeof(new_filename), "%s/%s/%s", |
770 | md->mdir_path, dir, msg->msg_uid); | 783 | md->mdir_path, dir, msg->msg_uid); |
771 | else | 784 | else |
772 | snprintf(new_filename, sizeof(new_filename), "%s/%s/%s:2,%s", | 785 | snprintf(new_filename, sizeof(new_filename), "%s/%s/%s:2,%s", |
773 | md->mdir_path, dir, msg->msg_uid, flag_str); | 786 | md->mdir_path, dir, msg->msg_uid, flag_str); |
774 | 787 | ||
775 | if (strcmp(filename, new_filename) == 0) | 788 | if (strcmp(filename, new_filename) == 0) |
776 | return MAILDIR_NO_ERROR; | 789 | return MAILDIR_NO_ERROR; |
777 | 790 | ||
778 | r = link(filename, new_filename); | 791 | r = link(filename, new_filename); |
779 | if (r == 0) { | 792 | if (r == 0) { |
780 | unlink(filename); | 793 | unlink(filename); |
781 | } | 794 | } |
782 | else if (errno == EXDEV) { | 795 | else if (errno == EXDEV) { |
783 | res = MAILDIR_ERROR_FOLDER; | 796 | res = MAILDIR_ERROR_FOLDER; |
784 | goto err; | 797 | goto err; |
785 | } | 798 | } |
786 | else if (errno == EPERM) { | 799 | else if (errno == EPERM) { |
787 | r = rename(filename, new_filename); | 800 | r = rename(filename, new_filename); |
788 | if (r < 0) { | 801 | if (r < 0) { |
789 | res = MAILDIR_ERROR_FOLDER; | 802 | res = MAILDIR_ERROR_FOLDER; |
790 | goto err; | 803 | goto err; |
791 | } | 804 | } |
792 | } | 805 | } |
793 | 806 | ||
794 | return MAILDIR_NO_ERROR; | 807 | return MAILDIR_NO_ERROR; |
795 | 808 | ||
796 | err: | 809 | err: |
797 | return res; | 810 | return res; |
798 | } | 811 | } |
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 | |||
@@ -155,835 +155,838 @@ struct mailmh_folder * mailmh_folder_new(struct mailmh_folder * parent, | |||
155 | folder->fl_msgs_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY); | 155 | folder->fl_msgs_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY); |
156 | if (folder->fl_msgs_hash == NULL) | 156 | if (folder->fl_msgs_hash == NULL) |
157 | goto free_msgs_tab; | 157 | goto free_msgs_tab; |
158 | 158 | ||
159 | folder->fl_subfolders_tab = carray_new(128); | 159 | folder->fl_subfolders_tab = carray_new(128); |
160 | if (folder->fl_subfolders_tab == NULL) | 160 | if (folder->fl_subfolders_tab == NULL) |
161 | goto free_msgs_hash; | 161 | goto free_msgs_hash; |
162 | 162 | ||
163 | folder->fl_subfolders_hash = chash_new(128, CHASH_COPYNONE); | 163 | folder->fl_subfolders_hash = chash_new(128, CHASH_COPYNONE); |
164 | if (folder->fl_subfolders_hash == NULL) | 164 | if (folder->fl_subfolders_hash == NULL) |
165 | goto free_subfolders_tab; | 165 | goto free_subfolders_tab; |
166 | 166 | ||
167 | folder->fl_mtime = 0; | 167 | folder->fl_mtime = 0; |
168 | folder->fl_parent = parent; | 168 | folder->fl_parent = parent; |
169 | folder->fl_max_index = 0; | 169 | folder->fl_max_index = 0; |
170 | 170 | ||
171 | return folder; | 171 | return folder; |
172 | 172 | ||
173 | free_subfolders_tab: | 173 | free_subfolders_tab: |
174 | carray_free(folder->fl_subfolders_tab); | 174 | carray_free(folder->fl_subfolders_tab); |
175 | free_msgs_hash: | 175 | free_msgs_hash: |
176 | #if 0 | 176 | #if 0 |
177 | cinthash_free(folder->fl_msgs_hash); | 177 | cinthash_free(folder->fl_msgs_hash); |
178 | #endif | 178 | #endif |
179 | chash_free(folder->fl_msgs_hash); | 179 | chash_free(folder->fl_msgs_hash); |
180 | free_msgs_tab: | 180 | free_msgs_tab: |
181 | carray_free(folder->fl_msgs_tab); | 181 | carray_free(folder->fl_msgs_tab); |
182 | free_name: | 182 | free_name: |
183 | free(folder->fl_name); | 183 | free(folder->fl_name); |
184 | free_filename: | 184 | free_filename: |
185 | free(folder->fl_filename); | 185 | free(folder->fl_filename); |
186 | free_folder: | 186 | free_folder: |
187 | free(folder); | 187 | free(folder); |
188 | err: | 188 | err: |
189 | return NULL; | 189 | return NULL; |
190 | } | 190 | } |
191 | 191 | ||
192 | void mailmh_folder_free(struct mailmh_folder * folder) | 192 | void mailmh_folder_free(struct mailmh_folder * folder) |
193 | { | 193 | { |
194 | unsigned int i; | 194 | unsigned int i; |
195 | 195 | ||
196 | for(i = 0 ; i < carray_count(folder->fl_subfolders_tab) ; i++) { | 196 | for(i = 0 ; i < carray_count(folder->fl_subfolders_tab) ; i++) { |
197 | struct mailmh_folder * subfolder; | 197 | struct mailmh_folder * subfolder; |
198 | 198 | ||
199 | subfolder = carray_get(folder->fl_subfolders_tab, i); | 199 | subfolder = carray_get(folder->fl_subfolders_tab, i); |
200 | if (subfolder != NULL) | 200 | if (subfolder != NULL) |
201 | mailmh_folder_free(subfolder); | 201 | mailmh_folder_free(subfolder); |
202 | } | 202 | } |
203 | carray_free(folder->fl_subfolders_tab); | 203 | carray_free(folder->fl_subfolders_tab); |
204 | chash_free(folder->fl_subfolders_hash); | 204 | chash_free(folder->fl_subfolders_hash); |
205 | 205 | ||
206 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) { | 206 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) { |
207 | struct mailmh_msg_info * msg_info; | 207 | struct mailmh_msg_info * msg_info; |
208 | 208 | ||
209 | msg_info = carray_get(folder->fl_msgs_tab, i); | 209 | msg_info = carray_get(folder->fl_msgs_tab, i); |
210 | if (msg_info != NULL) | 210 | if (msg_info != NULL) |
211 | mailmh_msg_info_free(msg_info); | 211 | mailmh_msg_info_free(msg_info); |
212 | } | 212 | } |
213 | carray_free(folder->fl_msgs_tab); | 213 | carray_free(folder->fl_msgs_tab); |
214 | chash_free(folder->fl_msgs_hash); | 214 | chash_free(folder->fl_msgs_hash); |
215 | #if 0 | 215 | #if 0 |
216 | cinthash_free(folder->fl_msgs_hash); | 216 | cinthash_free(folder->fl_msgs_hash); |
217 | #endif | 217 | #endif |
218 | 218 | ||
219 | free(folder->fl_filename); | 219 | free(folder->fl_filename); |
220 | free(folder->fl_name); | 220 | free(folder->fl_name); |
221 | 221 | ||
222 | free(folder); | 222 | free(folder); |
223 | } | 223 | } |
224 | 224 | ||
225 | struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root, | 225 | struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root, |
226 | const char * filename) | 226 | const char * filename) |
227 | { | 227 | { |
228 | int r; | 228 | int r; |
229 | char pathname[PATH_MAX]; | 229 | char pathname[PATH_MAX]; |
230 | char * p; | 230 | char * p; |
231 | chashdatum key; | 231 | chashdatum key; |
232 | chashdatum data; | 232 | chashdatum data; |
233 | struct mailmh_folder * folder; | 233 | struct mailmh_folder * folder; |
234 | char * start; | 234 | char * start; |
235 | 235 | ||
236 | if (strcmp(root->fl_filename, filename) == 0) | 236 | if (strcmp(root->fl_filename, filename) == 0) |
237 | return root; | 237 | return root; |
238 | 238 | ||
239 | #if 0 | 239 | #if 0 |
240 | r = mailmh_folder_update(root); | 240 | r = mailmh_folder_update(root); |
241 | if (r != MAILMH_NO_ERROR) | 241 | if (r != MAILMH_NO_ERROR) |
242 | return NULL; | 242 | return NULL; |
243 | #endif | 243 | #endif |
244 | 244 | ||
245 | #if 0 | 245 | #if 0 |
246 | for(i = 0 ; i < root->fl_subfolders_tab->len ; i++) { | 246 | for(i = 0 ; i < root->fl_subfolders_tab->len ; i++) { |
247 | struct mailmh_folder * subfolder; | 247 | struct mailmh_folder * subfolder; |
248 | 248 | ||
249 | subfolder = carray_get(root->fl_subfolders_tab, i); | 249 | subfolder = carray_get(root->fl_subfolders_tab, i); |
250 | if (subfolder != NULL) | 250 | if (subfolder != NULL) |
251 | if (strncmp(subfolder->fl_filename, filename, | 251 | if (strncmp(subfolder->fl_filename, filename, |
252 | strlen(subfolder->fl_filename)) == 0) | 252 | strlen(subfolder->fl_filename)) == 0) |
253 | return mailmh_folder_find(subfolder, filename); | 253 | return mailmh_folder_find(subfolder, filename); |
254 | } | 254 | } |
255 | #endif | 255 | #endif |
256 | strncpy(pathname, filename, PATH_MAX); | 256 | strncpy(pathname, filename, PATH_MAX); |
257 | pathname[PATH_MAX - 1] = 0; | 257 | pathname[PATH_MAX - 1] = 0; |
258 | start = pathname + strlen(root->fl_filename) + 1; | 258 | start = pathname + strlen(root->fl_filename) + 1; |
259 | 259 | ||
260 | p = strchr(start, MAIL_DIR_SEPARATOR); | 260 | p = strchr(start, MAIL_DIR_SEPARATOR); |
261 | if (p != NULL) { | 261 | if (p != NULL) { |
262 | * p = 0; | 262 | * p = 0; |
263 | 263 | ||
264 | root = mailmh_folder_find(root, pathname); | 264 | root = mailmh_folder_find(root, pathname); |
265 | if (root != NULL) { | 265 | if (root != NULL) { |
266 | folder = mailmh_folder_find(root, filename); | 266 | folder = mailmh_folder_find(root, filename); |
267 | if (folder == NULL) | 267 | if (folder == NULL) |
268 | return NULL; | 268 | return NULL; |
269 | return folder; | 269 | return folder; |
270 | } | 270 | } |
271 | 271 | ||
272 | return NULL; | 272 | return NULL; |
273 | } | 273 | } |
274 | else { | 274 | else { |
275 | key.data = pathname; | 275 | key.data = pathname; |
276 | key.len = strlen(pathname); | 276 | key.len = strlen(pathname); |
277 | r = chash_get(root->fl_subfolders_hash, &key, &data); | 277 | r = chash_get(root->fl_subfolders_hash, &key, &data); |
278 | if (r < 0) | 278 | if (r < 0) |
279 | return NULL; | 279 | return NULL; |
280 | 280 | ||
281 | return data.data; | 281 | return data.data; |
282 | } | 282 | } |
283 | } | 283 | } |
284 | 284 | ||
285 | int mailmh_folder_update(struct mailmh_folder * folder) | 285 | int mailmh_folder_update(struct mailmh_folder * folder) |
286 | { | 286 | { |
287 | DIR * d; | 287 | DIR * d; |
288 | struct dirent * ent; | 288 | struct dirent * ent; |
289 | struct stat buf; | 289 | struct stat buf; |
290 | char * mh_seq; | 290 | char * mh_seq; |
291 | char filename[PATH_MAX]; | 291 | char filename[PATH_MAX]; |
292 | int res; | 292 | int res; |
293 | int r; | 293 | int r; |
294 | uint32_t max_index; | 294 | uint32_t max_index; |
295 | #if 0 | 295 | #if 0 |
296 | int add_folder; | 296 | int add_folder; |
297 | #endif | 297 | #endif |
298 | unsigned int i; | 298 | unsigned int i; |
299 | 299 | ||
300 | if (stat(folder->fl_filename, &buf) == -1) { | 300 | if (stat(folder->fl_filename, &buf) == -1) { |
301 | res = MAILMH_ERROR_FOLDER; | 301 | res = MAILMH_ERROR_FOLDER; |
302 | goto err; | 302 | goto err; |
303 | } | 303 | } |
304 | 304 | ||
305 | if (folder->fl_mtime == buf.st_mtime) { | 305 | if (folder->fl_mtime == buf.st_mtime) { |
306 | res = MAILMH_NO_ERROR; | 306 | res = MAILMH_NO_ERROR; |
307 | goto err; | 307 | goto err; |
308 | } | 308 | } |
309 | 309 | ||
310 | folder->fl_mtime = buf.st_mtime; | 310 | folder->fl_mtime = buf.st_mtime; |
311 | 311 | ||
312 | d = opendir(folder->fl_filename); | 312 | d = opendir(folder->fl_filename); |
313 | if (d == NULL) { | 313 | if (d == NULL) { |
314 | res = MAILMH_ERROR_FOLDER; | 314 | res = MAILMH_ERROR_FOLDER; |
315 | goto err; | 315 | goto err; |
316 | } | 316 | } |
317 | 317 | ||
318 | max_index = 0; | 318 | max_index = 0; |
319 | 319 | ||
320 | #if 0 | 320 | #if 0 |
321 | if (folder->fl_subfolders_tab->len == 0) | 321 | if (folder->fl_subfolders_tab->len == 0) |
322 | add_folder = 1; | 322 | add_folder = 1; |
323 | else | 323 | else |
324 | add_folder = 0; | 324 | add_folder = 0; |
325 | #endif | 325 | #endif |
326 | 326 | ||
327 | /* clear the message list */ | 327 | /* clear the message list */ |
328 | 328 | ||
329 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) { | 329 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) { |
330 | struct mailmh_msg_info * msg_info; | 330 | struct mailmh_msg_info * msg_info; |
331 | chashdatum key; | 331 | chashdatum key; |
332 | 332 | ||
333 | msg_info = carray_get(folder->fl_msgs_tab, i); | 333 | msg_info = carray_get(folder->fl_msgs_tab, i); |
334 | if (msg_info == NULL) | 334 | if (msg_info == NULL) |
335 | continue; | 335 | continue; |
336 | 336 | ||
337 | #if 0 | 337 | #if 0 |
338 | cinthash_remove(folder->fl_msgs_hash, msg_info->msg_index); | 338 | cinthash_remove(folder->fl_msgs_hash, msg_info->msg_index); |
339 | #endif | 339 | #endif |
340 | key.data = &msg_info->msg_index; | 340 | key.data = &msg_info->msg_index; |
341 | key.len = sizeof(msg_info->msg_index); | 341 | key.len = sizeof(msg_info->msg_index); |
342 | chash_delete(folder->fl_msgs_hash, &key, NULL); | 342 | chash_delete(folder->fl_msgs_hash, &key, NULL); |
343 | 343 | ||
344 | mailmh_msg_info_free(msg_info); | 344 | mailmh_msg_info_free(msg_info); |
345 | } | 345 | } |
346 | 346 | ||
347 | carray_set_size(folder->fl_msgs_tab, 0); | 347 | carray_set_size(folder->fl_msgs_tab, 0); |
348 | 348 | ||
349 | do { | 349 | do { |
350 | uint32_t index; | 350 | uint32_t index; |
351 | 351 | ||
352 | ent = readdir(d); | 352 | ent = readdir(d); |
353 | 353 | ||
354 | if (ent != NULL) { | 354 | if (ent != NULL) { |
355 | 355 | ||
356 | snprintf(filename, PATH_MAX, | 356 | snprintf(filename, PATH_MAX, |
357 | "%s%c%s", folder->fl_filename, MAIL_DIR_SEPARATOR, ent->d_name); | 357 | "%s%c%s", folder->fl_filename, MAIL_DIR_SEPARATOR, ent->d_name); |
358 | 358 | ||
359 | if (stat(filename, &buf) == -1) | 359 | if (stat(filename, &buf) == -1) |
360 | continue; | 360 | continue; |
361 | 361 | ||
362 | if (S_ISREG(buf.st_mode)) { | 362 | if (S_ISREG(buf.st_mode)) { |
363 | index = strtoul(ent->d_name, NULL, 10); | 363 | index = strtoul(ent->d_name, NULL, 10); |
364 | if (index != 0) { | 364 | if (index != 0) { |
365 | struct mailmh_msg_info * msg_info; | 365 | struct mailmh_msg_info * msg_info; |
366 | unsigned int array_index; | 366 | unsigned int array_index; |
367 | chashdatum key; | 367 | chashdatum key; |
368 | chashdatum data; | 368 | chashdatum data; |
369 | 369 | ||
370 | msg_info = mailmh_msg_info_new(index, buf.st_size, buf.st_mtime); | 370 | msg_info = mailmh_msg_info_new(index, buf.st_size, buf.st_mtime); |
371 | if (msg_info == NULL) { | 371 | if (msg_info == NULL) { |
372 | res = MAILMH_ERROR_MEMORY; | 372 | res = MAILMH_ERROR_MEMORY; |
373 | goto closedir; | 373 | goto closedir; |
374 | } | 374 | } |
375 | 375 | ||
376 | r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); | 376 | r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); |
377 | if (r < 0) { | 377 | if (r < 0) { |
378 | mailmh_msg_info_free(msg_info); | 378 | mailmh_msg_info_free(msg_info); |
379 | res = MAILMH_ERROR_MEMORY; | 379 | res = MAILMH_ERROR_MEMORY; |
380 | goto closedir; | 380 | goto closedir; |
381 | } | 381 | } |
382 | msg_info->msg_array_index = array_index; | 382 | msg_info->msg_array_index = array_index; |
383 | 383 | ||
384 | if (index > max_index) | 384 | if (index > max_index) |
385 | max_index = index; | 385 | max_index = index; |
386 | 386 | ||
387 | #if 0 | 387 | #if 0 |
388 | r = cinthash_add(folder->fl_msgs_hash, msg_info->msg_index, msg_info); | 388 | r = cinthash_add(folder->fl_msgs_hash, msg_info->msg_index, msg_info); |
389 | #endif | 389 | #endif |
390 | key.data = &msg_info->msg_index; | 390 | key.data = &msg_info->msg_index; |
391 | key.len = sizeof(msg_info->msg_index); | 391 | key.len = sizeof(msg_info->msg_index); |
392 | data.data = msg_info; | 392 | data.data = msg_info; |
393 | data.len = 0; | 393 | data.len = 0; |
394 | 394 | ||
395 | r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); | 395 | r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); |
396 | if (r < 0) { | 396 | if (r < 0) { |
397 | carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); | 397 | carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); |
398 | mailmh_msg_info_free(msg_info); | 398 | mailmh_msg_info_free(msg_info); |
399 | res = MAILMH_ERROR_MEMORY; | 399 | res = MAILMH_ERROR_MEMORY; |
400 | goto closedir; | 400 | goto closedir; |
401 | } | 401 | } |
402 | } | 402 | } |
403 | } | 403 | } |
404 | else if (S_ISDIR(buf.st_mode)) { | 404 | else if (S_ISDIR(buf.st_mode)) { |
405 | struct mailmh_folder * subfolder; | 405 | struct mailmh_folder * subfolder; |
406 | unsigned int array_index; | 406 | unsigned int array_index; |
407 | chashdatum key; | 407 | chashdatum key; |
408 | chashdatum data; | 408 | chashdatum data; |
409 | 409 | ||
410 | if (ent->d_name[0] == '.') { | 410 | if (ent->d_name[0] == '.') { |
411 | if (ent->d_name[1] == 0) | 411 | if (ent->d_name[1] == 0) |
412 | continue; | 412 | continue; |
413 | if ((ent->d_name[1] == '.') && (ent->d_name[2] == 0)) | 413 | if ((ent->d_name[1] == '.') && (ent->d_name[2] == 0)) |
414 | continue; | 414 | continue; |
415 | } | 415 | } |
416 | 416 | ||
417 | key.data = ent->d_name; | 417 | key.data = ent->d_name; |
418 | key.len = strlen(ent->d_name); | 418 | key.len = strlen(ent->d_name); |
419 | r = chash_get(folder->fl_subfolders_hash, &key, &data); | 419 | r = chash_get(folder->fl_subfolders_hash, &key, &data); |
420 | if (r < 0) { | 420 | if (r < 0) { |
421 | subfolder = mailmh_folder_new(folder, ent->d_name); | 421 | subfolder = mailmh_folder_new(folder, ent->d_name); |
422 | if (subfolder == NULL) { | 422 | if (subfolder == NULL) { |
423 | res = MAILMH_ERROR_MEMORY; | 423 | res = MAILMH_ERROR_MEMORY; |
424 | goto closedir; | 424 | goto closedir; |
425 | } | 425 | } |
426 | 426 | ||
427 | r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index); | 427 | r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index); |
428 | if (r < 0) { | 428 | if (r < 0) { |
429 | mailmh_folder_free(subfolder); | 429 | mailmh_folder_free(subfolder); |
430 | res = MAILMH_ERROR_MEMORY; | 430 | res = MAILMH_ERROR_MEMORY; |
431 | goto closedir; | 431 | goto closedir; |
432 | } | 432 | } |
433 | subfolder->fl_array_index = array_index; | 433 | subfolder->fl_array_index = array_index; |
434 | 434 | ||
435 | key.data = subfolder->fl_filename; | 435 | key.data = subfolder->fl_filename; |
436 | key.len = strlen(subfolder->fl_filename); | 436 | key.len = strlen(subfolder->fl_filename); |
437 | data.data = subfolder; | 437 | data.data = subfolder; |
438 | data.len = 0; | 438 | data.len = 0; |
439 | r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL); | 439 | r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL); |
440 | if (r < 0) { | 440 | if (r < 0) { |
441 | carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index); | 441 | carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index); |
442 | mailmh_folder_free(subfolder); | 442 | mailmh_folder_free(subfolder); |
443 | res = MAILMH_ERROR_MEMORY; | 443 | res = MAILMH_ERROR_MEMORY; |
444 | goto closedir; | 444 | goto closedir; |
445 | } | 445 | } |
446 | } | 446 | } |
447 | } | 447 | } |
448 | } | 448 | } |
449 | } | 449 | } |
450 | while (ent != NULL); | 450 | while (ent != NULL); |
451 | 451 | ||
452 | folder->fl_max_index = max_index; | 452 | folder->fl_max_index = max_index; |
453 | 453 | ||
454 | mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences")); | 454 | mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences")); |
455 | if (mh_seq == NULL) { | 455 | if (mh_seq == NULL) { |
456 | res = MAILMH_ERROR_MEMORY; | 456 | res = MAILMH_ERROR_MEMORY; |
457 | goto closedir; | 457 | goto closedir; |
458 | } | 458 | } |
459 | strcpy(mh_seq, folder->fl_filename); | 459 | strcpy(mh_seq, folder->fl_filename); |
460 | strcat(mh_seq, MAIL_DIR_SEPARATOR_S); | 460 | strcat(mh_seq, MAIL_DIR_SEPARATOR_S); |
461 | strcat(mh_seq, ".mh_sequences"); | 461 | strcat(mh_seq, ".mh_sequences"); |
462 | 462 | ||
463 | if (stat(mh_seq, &buf) == -1) { | 463 | if (stat(mh_seq, &buf) == -1) { |
464 | int fd; | 464 | int fd; |
465 | 465 | ||
466 | fd = creat(mh_seq, S_IRUSR | S_IWUSR); | 466 | fd = creat(mh_seq, S_IRUSR | S_IWUSR); |
467 | if (fd != -1) | 467 | if (fd != -1) |
468 | close(fd); | 468 | close(fd); |
469 | } | 469 | } |
470 | free(mh_seq); | 470 | free(mh_seq); |
471 | 471 | ||
472 | closedir(d); | 472 | closedir(d); |
473 | 473 | ||
474 | return MAILMH_NO_ERROR; | 474 | return MAILMH_NO_ERROR; |
475 | 475 | ||
476 | closedir: | 476 | closedir: |
477 | closedir(d); | 477 | closedir(d); |
478 | err: | 478 | err: |
479 | return res; | 479 | return res; |
480 | } | 480 | } |
481 | 481 | ||
482 | int mailmh_folder_add_subfolder(struct mailmh_folder * parent, | 482 | int mailmh_folder_add_subfolder(struct mailmh_folder * parent, |
483 | const char * name) | 483 | const char * name) |
484 | { | 484 | { |
485 | char * foldername; | 485 | char * foldername; |
486 | int r; | 486 | int r; |
487 | struct mailmh_folder * folder; | 487 | struct mailmh_folder * folder; |
488 | unsigned int array_index; | 488 | unsigned int array_index; |
489 | chashdatum key; | 489 | chashdatum key; |
490 | chashdatum data; | 490 | chashdatum data; |
491 | 491 | ||
492 | foldername = malloc(strlen(parent->fl_filename) + strlen(name) + 2); | 492 | foldername = malloc(strlen(parent->fl_filename) + strlen(name) + 2); |
493 | if (foldername == NULL) | 493 | if (foldername == NULL) |
494 | return MAILMH_ERROR_MEMORY; | 494 | return MAILMH_ERROR_MEMORY; |
495 | strcpy(foldername, parent->fl_filename); | 495 | strcpy(foldername, parent->fl_filename); |
496 | strcat(foldername, MAIL_DIR_SEPARATOR_S); | 496 | strcat(foldername, MAIL_DIR_SEPARATOR_S); |
497 | strcat(foldername, name); | 497 | strcat(foldername, name); |
498 | 498 | ||
499 | r = mkdir(foldername, 0700); | 499 | r = mkdir(foldername, 0700); |
500 | free(foldername); | 500 | free(foldername); |
501 | 501 | ||
502 | if (r < 0) | 502 | if (r < 0) |
503 | return MAILMH_ERROR_FOLDER; | 503 | return MAILMH_ERROR_FOLDER; |
504 | 504 | ||
505 | folder = mailmh_folder_new(parent, name); | 505 | folder = mailmh_folder_new(parent, name); |
506 | if (folder == NULL) | 506 | if (folder == NULL) |
507 | return MAILMH_ERROR_MEMORY; | 507 | return MAILMH_ERROR_MEMORY; |
508 | 508 | ||
509 | r = carray_add(parent->fl_subfolders_tab, folder, &array_index); | 509 | r = carray_add(parent->fl_subfolders_tab, folder, &array_index); |
510 | if (r < 0) { | 510 | if (r < 0) { |
511 | mailmh_folder_free(folder); | 511 | mailmh_folder_free(folder); |
512 | return MAILMH_ERROR_MEMORY; | 512 | return MAILMH_ERROR_MEMORY; |
513 | } | 513 | } |
514 | folder->fl_array_index = array_index; | 514 | folder->fl_array_index = array_index; |
515 | 515 | ||
516 | key.data = folder->fl_filename; | 516 | key.data = folder->fl_filename; |
517 | key.len = strlen(folder->fl_filename); | 517 | key.len = strlen(folder->fl_filename); |
518 | data.data = folder; | 518 | data.data = folder; |
519 | data.len = 0; | 519 | data.len = 0; |
520 | 520 | ||
521 | r = chash_set(parent->fl_subfolders_hash, &key, &data, NULL); | 521 | r = chash_set(parent->fl_subfolders_hash, &key, &data, NULL); |
522 | if (r < 0) { | 522 | if (r < 0) { |
523 | carray_delete_fast(folder->fl_subfolders_tab, folder->fl_array_index); | 523 | carray_delete_fast(folder->fl_subfolders_tab, folder->fl_array_index); |
524 | mailmh_folder_free(folder); | 524 | mailmh_folder_free(folder); |
525 | return MAILMH_ERROR_MEMORY; | 525 | return MAILMH_ERROR_MEMORY; |
526 | } | 526 | } |
527 | 527 | ||
528 | return MAILMH_NO_ERROR; | 528 | return MAILMH_NO_ERROR; |
529 | } | 529 | } |
530 | 530 | ||
531 | int mailmh_folder_remove_subfolder(struct mailmh_folder * folder) | 531 | int mailmh_folder_remove_subfolder(struct mailmh_folder * folder) |
532 | { | 532 | { |
533 | struct mailmh_folder * parent; | 533 | struct mailmh_folder * parent; |
534 | chashdatum key; | 534 | chashdatum key; |
535 | chashdatum data; | 535 | chashdatum data; |
536 | int r; | 536 | int r; |
537 | 537 | ||
538 | parent = folder->fl_parent; | 538 | parent = folder->fl_parent; |
539 | 539 | ||
540 | key.data = folder->fl_filename; | 540 | key.data = folder->fl_filename; |
541 | key.len = strlen(folder->fl_filename); | 541 | key.len = strlen(folder->fl_filename); |
542 | 542 | ||
543 | r = chash_get(parent->fl_subfolders_hash, &key, &data); | 543 | r = chash_get(parent->fl_subfolders_hash, &key, &data); |
544 | if (r < 0) | 544 | if (r < 0) |
545 | return MAILMH_ERROR_FOLDER; | 545 | return MAILMH_ERROR_FOLDER; |
546 | 546 | ||
547 | chash_delete(parent->fl_subfolders_hash, &key, NULL); | 547 | chash_delete(parent->fl_subfolders_hash, &key, NULL); |
548 | carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index); | 548 | carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index); |
549 | 549 | ||
550 | mailmh_folder_free(folder); | 550 | mailmh_folder_free(folder); |
551 | 551 | ||
552 | return MAILMH_NO_ERROR; | 552 | return MAILMH_NO_ERROR; |
553 | 553 | ||
554 | } | 554 | } |
555 | 555 | ||
556 | int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder, | 556 | int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder, |
557 | struct mailmh_folder * dst_folder, | 557 | struct mailmh_folder * dst_folder, |
558 | const char * new_name) | 558 | const char * new_name) |
559 | { | 559 | { |
560 | int r; | 560 | int r; |
561 | struct mailmh_folder * folder; | 561 | struct mailmh_folder * folder; |
562 | struct mailmh_folder * parent; | 562 | struct mailmh_folder * parent; |
563 | char * new_foldername; | 563 | char * new_foldername; |
564 | 564 | ||
565 | parent = src_folder->fl_parent; | 565 | parent = src_folder->fl_parent; |
566 | if (parent == NULL) | 566 | if (parent == NULL) |
567 | return MAILMH_ERROR_RENAME; | 567 | return MAILMH_ERROR_RENAME; |
568 | 568 | ||
569 | new_foldername = malloc(strlen(dst_folder->fl_filename) + 2 + strlen(new_name)); | 569 | new_foldername = malloc(strlen(dst_folder->fl_filename) + 2 + strlen(new_name)); |
570 | if (new_foldername == NULL) | 570 | if (new_foldername == NULL) |
571 | return MAILMH_ERROR_MEMORY; | 571 | return MAILMH_ERROR_MEMORY; |
572 | 572 | ||
573 | strcpy(new_foldername, dst_folder->fl_filename); | 573 | strcpy(new_foldername, dst_folder->fl_filename); |
574 | strcat(new_foldername, MAIL_DIR_SEPARATOR_S); | 574 | strcat(new_foldername, MAIL_DIR_SEPARATOR_S); |
575 | strcat(new_foldername, new_name); | 575 | strcat(new_foldername, new_name); |
576 | 576 | ||
577 | r = rename(src_folder->fl_filename, new_foldername); | 577 | r = rename(src_folder->fl_filename, new_foldername); |
578 | free(new_foldername); | 578 | free(new_foldername); |
579 | if (r < 0) | 579 | if (r < 0) |
580 | return MAILMH_ERROR_RENAME; | 580 | return MAILMH_ERROR_RENAME; |
581 | 581 | ||
582 | r = mailmh_folder_remove_subfolder(src_folder); | 582 | r = mailmh_folder_remove_subfolder(src_folder); |
583 | if (r != MAILMH_NO_ERROR) | 583 | if (r != MAILMH_NO_ERROR) |
584 | return r; | 584 | return r; |
585 | 585 | ||
586 | folder = mailmh_folder_new(dst_folder, new_name); | 586 | folder = mailmh_folder_new(dst_folder, new_name); |
587 | if (folder == NULL) | 587 | if (folder == NULL) |
588 | return MAILMH_ERROR_MEMORY; | 588 | return MAILMH_ERROR_MEMORY; |
589 | 589 | ||
590 | r = carray_add(parent->fl_subfolders_tab, folder, NULL); | 590 | r = carray_add(parent->fl_subfolders_tab, folder, NULL); |
591 | if (r < 0) { | 591 | if (r < 0) { |
592 | mailmh_folder_free(folder); | 592 | mailmh_folder_free(folder); |
593 | return MAILMH_ERROR_MEMORY; | 593 | return MAILMH_ERROR_MEMORY; |
594 | } | 594 | } |
595 | 595 | ||
596 | return MAILMH_NO_ERROR; | 596 | return MAILMH_NO_ERROR; |
597 | } | 597 | } |
598 | 598 | ||
599 | #define MAX_TRY_ALLOC 32 | 599 | #define MAX_TRY_ALLOC 32 |
600 | 600 | ||
601 | /* initial file MUST be in the same directory */ | 601 | /* initial file MUST be in the same directory */ |
602 | 602 | ||
603 | static int mailmh_folder_alloc_msg(struct mailmh_folder * folder, | 603 | static int mailmh_folder_alloc_msg(struct mailmh_folder * folder, |
604 | char * filename, uint32_t * result) | 604 | char * filename, uint32_t * result) |
605 | { | 605 | { |
606 | uint32_t max; | 606 | uint32_t max; |
607 | uint32_t k; | 607 | uint32_t k; |
608 | char * new_filename; | 608 | char * new_filename; |
609 | size_t len; | 609 | size_t len; |
610 | int got_file; | 610 | int got_file; |
611 | int r; | 611 | int r; |
612 | 612 | ||
613 | len = strlen(folder->fl_filename) + 20; | 613 | len = strlen(folder->fl_filename) + 20; |
614 | new_filename = malloc(len); | 614 | new_filename = malloc(len); |
615 | if (new_filename == NULL) | 615 | if (new_filename == NULL) |
616 | return MAILMH_ERROR_MEMORY; | 616 | return MAILMH_ERROR_MEMORY; |
617 | 617 | ||
618 | max = folder->fl_max_index + 1; | 618 | max = folder->fl_max_index + 1; |
619 | 619 | ||
620 | got_file = 0; | 620 | got_file = 0; |
621 | k = 0; | 621 | k = 0; |
622 | while (k < MAX_TRY_ALLOC) { | 622 | while (k < MAX_TRY_ALLOC) { |
623 | snprintf(new_filename, len, "%s%c%lu", folder->fl_filename, | 623 | snprintf(new_filename, len, "%s%c%lu", folder->fl_filename, |
624 | MAIL_DIR_SEPARATOR, (unsigned long) (max + k)); | 624 | MAIL_DIR_SEPARATOR, (unsigned long) (max + k)); |
625 | 625 | ||
626 | if (link(filename, new_filename) == 0) { | 626 | if (link(filename, new_filename) == 0) { |
627 | unlink(filename); | 627 | unlink(filename); |
628 | } | 628 | } |
629 | else if (errno == EXDEV) { | 629 | else if (errno == EXDEV) { |
630 | free(filename); | 630 | free(filename); |
631 | return MAILMH_ERROR_FOLDER; | 631 | return MAILMH_ERROR_FOLDER; |
632 | } | 632 | } |
633 | else if (errno == EPERM) { | 633 | else if (errno == EPERM) { |
634 | rename(filename, new_filename); | 634 | rename(filename, new_filename); |
635 | got_file = 1; | 635 | got_file = 1; |
636 | } | 636 | } |
637 | 637 | ||
638 | if (got_file) { | 638 | if (got_file) { |
639 | free(new_filename); | 639 | free(new_filename); |
640 | 640 | ||
641 | if (k > MAX_TRY_ALLOC / 2) { | 641 | if (k > MAX_TRY_ALLOC / 2) { |
642 | r = mailmh_folder_update(folder); | 642 | r = mailmh_folder_update(folder); |
643 | /* ignore errors */ | 643 | /* ignore errors */ |
644 | } | 644 | } |
645 | 645 | ||
646 | * result = max + k; | 646 | * result = max + k; |
647 | 647 | ||
648 | folder->fl_max_index = max + k; | 648 | folder->fl_max_index = max + k; |
649 | 649 | ||
650 | return MAILMH_NO_ERROR; | 650 | return MAILMH_NO_ERROR; |
651 | } | 651 | } |
652 | k ++; | 652 | k ++; |
653 | } | 653 | } |
654 | 654 | ||
655 | free(new_filename); | 655 | free(new_filename); |
656 | 656 | ||
657 | return MAILMH_ERROR_FOLDER; | 657 | return MAILMH_ERROR_FOLDER; |
658 | } | 658 | } |
659 | 659 | ||
660 | int mailmh_folder_get_message_filename(struct mailmh_folder * folder, | 660 | int mailmh_folder_get_message_filename(struct mailmh_folder * folder, |
661 | uint32_t index, char ** result) | 661 | uint32_t index, char ** result) |
662 | { | 662 | { |
663 | char * filename; | 663 | char * filename; |
664 | int len; | 664 | int len; |
665 | 665 | ||
666 | #if 0 | 666 | #if 0 |
667 | r = mailmh_folder_update(folder); | 667 | r = mailmh_folder_update(folder); |
668 | if (r != MAILMH_NO_ERROR) | 668 | if (r != MAILMH_NO_ERROR) |
669 | return r; | 669 | return r; |
670 | #endif | 670 | #endif |
671 | 671 | ||
672 | len = strlen(folder->fl_filename) + 20; | 672 | len = strlen(folder->fl_filename) + 20; |
673 | filename = malloc(len); | 673 | filename = malloc(len); |
674 | if (filename == NULL) | 674 | if (filename == NULL) |
675 | return MAILMH_ERROR_MEMORY; | 675 | return MAILMH_ERROR_MEMORY; |
676 | 676 | ||
677 | snprintf(filename, len, "%s%c%lu", folder->fl_filename, MAIL_DIR_SEPARATOR, | 677 | snprintf(filename, len, "%s%c%lu", folder->fl_filename, MAIL_DIR_SEPARATOR, |
678 | (unsigned long) index); | 678 | (unsigned long) index); |
679 | 679 | ||
680 | * result = filename; | 680 | * result = filename; |
681 | 681 | ||
682 | return MAILMH_NO_ERROR;; | 682 | return MAILMH_NO_ERROR;; |
683 | } | 683 | } |
684 | 684 | ||
685 | 685 | ||
686 | int mailmh_folder_get_message_fd(struct mailmh_folder * folder, | 686 | int mailmh_folder_get_message_fd(struct mailmh_folder * folder, |
687 | uint32_t index, int flags, int * result) | 687 | uint32_t index, int flags, int * result) |
688 | { | 688 | { |
689 | char * filename; | 689 | char * filename; |
690 | int fd; | 690 | int fd; |
691 | int r; | 691 | int r; |
692 | 692 | ||
693 | #if 0 | 693 | #if 0 |
694 | r = mailmh_folder_update(folder); | 694 | r = mailmh_folder_update(folder); |
695 | if (r != MAILMH_NO_ERROR) | 695 | if (r != MAILMH_NO_ERROR) |
696 | return r; | 696 | return r; |
697 | #endif | 697 | #endif |
698 | 698 | ||
699 | r = mailmh_folder_get_message_filename(folder, index, &filename); | 699 | r = mailmh_folder_get_message_filename(folder, index, &filename); |
700 | if (r != MAILMH_NO_ERROR) | 700 | if (r != MAILMH_NO_ERROR) |
701 | return r; | 701 | return r; |
702 | 702 | ||
703 | fd = open(filename, flags); | 703 | fd = open(filename, flags); |
704 | free(filename); | 704 | free(filename); |
705 | if (fd == -1) | 705 | if (fd == -1) |
706 | return MAILMH_ERROR_MSG_NOT_FOUND; | 706 | return MAILMH_ERROR_MSG_NOT_FOUND; |
707 | 707 | ||
708 | * result = fd; | 708 | * result = fd; |
709 | 709 | ||
710 | return MAILMH_NO_ERROR; | 710 | return MAILMH_NO_ERROR; |
711 | } | 711 | } |
712 | 712 | ||
713 | int mailmh_folder_get_message_size(struct mailmh_folder * folder, | 713 | int mailmh_folder_get_message_size(struct mailmh_folder * folder, |
714 | uint32_t index, size_t * result) | 714 | uint32_t index, size_t * result) |
715 | { | 715 | { |
716 | int r; | 716 | int r; |
717 | char * filename; | 717 | char * filename; |
718 | struct stat buf; | 718 | struct stat buf; |
719 | 719 | ||
720 | r = mailmh_folder_get_message_filename(folder, index, &filename); | 720 | r = mailmh_folder_get_message_filename(folder, index, &filename); |
721 | if (r != MAILMH_NO_ERROR) | 721 | if (r != MAILMH_NO_ERROR) |
722 | return r; | 722 | return r; |
723 | 723 | ||
724 | r = stat(filename, &buf); | 724 | r = stat(filename, &buf); |
725 | free(filename); | 725 | free(filename); |
726 | if (r < 0) | 726 | if (r < 0) |
727 | return MAILMH_ERROR_FILE; | 727 | return MAILMH_ERROR_FILE; |
728 | 728 | ||
729 | * result = buf.st_size; | 729 | * result = buf.st_size; |
730 | 730 | ||
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 | |||
@@ -1,1230 +1,1233 @@ | |||
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 | /* | 36 | /* |
37 | POP3 Protocol | 37 | POP3 Protocol |
38 | 38 | ||
39 | RFC 1734 | 39 | RFC 1734 |
40 | RFC 1939 | 40 | RFC 1939 |
41 | RFC 2449 | 41 | RFC 2449 |
42 | 42 | ||
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include "mailpop3.h" | 45 | #include "mailpop3.h" |
46 | #include <stdio.h> | 46 | #include <stdio.h> |
47 | #include <string.h> | 47 | #include <string.h> |
48 | #include "md5.h" | 48 | #include "md5.h" |
49 | #include "mail.h" | 49 | #include "mail.h" |
50 | #include <stdlib.h> | 50 | #include <stdlib.h> |
51 | 51 | ||
52 | 52 | ||
53 | 53 | ||
54 | 54 | ||
55 | enum { | 55 | enum { |
56 | POP3_STATE_DISCONNECTED, | 56 | POP3_STATE_DISCONNECTED, |
57 | POP3_STATE_AUTHORIZATION, | 57 | POP3_STATE_AUTHORIZATION, |
58 | POP3_STATE_TRANSACTION | 58 | POP3_STATE_TRANSACTION |
59 | }; | 59 | }; |
60 | 60 | ||
61 | 61 | ||
62 | 62 | ||
63 | /* | 63 | /* |
64 | mailpop3_msg_info structure | 64 | mailpop3_msg_info structure |
65 | */ | 65 | */ |
66 | 66 | ||
67 | static struct mailpop3_msg_info * | 67 | static struct mailpop3_msg_info * |
68 | mailpop3_msg_info_new(unsigned int index, uint32_t size, char * uidl) | 68 | mailpop3_msg_info_new(unsigned int index, uint32_t size, char * uidl) |
69 | { | 69 | { |
70 | struct mailpop3_msg_info * msg; | 70 | struct mailpop3_msg_info * msg; |
71 | 71 | ||
72 | msg = malloc(sizeof(* msg)); | 72 | msg = malloc(sizeof(* msg)); |
73 | if (msg == NULL) | 73 | if (msg == NULL) |
74 | return NULL; | 74 | return NULL; |
75 | msg->msg_index = index; | 75 | msg->msg_index = index; |
76 | msg->msg_size = size; | 76 | msg->msg_size = size; |
77 | msg->msg_deleted = FALSE; | 77 | msg->msg_deleted = FALSE; |
78 | msg->msg_uidl = uidl; | 78 | msg->msg_uidl = uidl; |
79 | 79 | ||
80 | return msg; | 80 | return msg; |
81 | } | 81 | } |
82 | 82 | ||
83 | static void mailpop3_msg_info_free(struct mailpop3_msg_info * msg) | 83 | static void mailpop3_msg_info_free(struct mailpop3_msg_info * msg) |
84 | { | 84 | { |
85 | if (msg->msg_uidl != NULL) | 85 | if (msg->msg_uidl != NULL) |
86 | free(msg->msg_uidl); | 86 | free(msg->msg_uidl); |
87 | free(msg); | 87 | free(msg); |
88 | } | 88 | } |
89 | 89 | ||
90 | static void mailpop3_msg_info_tab_free(carray * msg_tab) | 90 | static void mailpop3_msg_info_tab_free(carray * msg_tab) |
91 | { | 91 | { |
92 | unsigned int i; | 92 | unsigned int i; |
93 | 93 | ||
94 | for(i = 0 ; i < carray_count(msg_tab) ; i++) { | 94 | for(i = 0 ; i < carray_count(msg_tab) ; i++) { |
95 | struct mailpop3_msg_info * msg; | 95 | struct mailpop3_msg_info * msg; |
96 | 96 | ||
97 | msg = carray_get(msg_tab, i); | 97 | msg = carray_get(msg_tab, i); |
98 | mailpop3_msg_info_free(msg); | 98 | mailpop3_msg_info_free(msg); |
99 | } | 99 | } |
100 | carray_free(msg_tab); | 100 | carray_free(msg_tab); |
101 | } | 101 | } |
102 | 102 | ||
103 | static void mailpop3_msg_info_tab_reset(carray * msg_tab) | 103 | static void mailpop3_msg_info_tab_reset(carray * msg_tab) |
104 | { | 104 | { |
105 | unsigned int i; | 105 | unsigned int i; |
106 | 106 | ||
107 | for(i = 0 ; i < carray_count(msg_tab) ; i++) { | 107 | for(i = 0 ; i < carray_count(msg_tab) ; i++) { |
108 | struct mailpop3_msg_info * msg; | 108 | struct mailpop3_msg_info * msg; |
109 | msg = carray_get(msg_tab, i); | 109 | msg = carray_get(msg_tab, i); |
110 | msg->msg_deleted = FALSE; | 110 | msg->msg_deleted = FALSE; |
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | static inline struct mailpop3_msg_info * | 114 | static inline struct mailpop3_msg_info * |
115 | mailpop3_msg_info_tab_find_msg(carray * msg_tab, unsigned int index) | 115 | mailpop3_msg_info_tab_find_msg(carray * msg_tab, unsigned int index) |
116 | { | 116 | { |
117 | struct mailpop3_msg_info * msg; | 117 | struct mailpop3_msg_info * msg; |
118 | 118 | ||
119 | if (index == 0) | 119 | if (index == 0) |
120 | return NULL; | 120 | return NULL; |
121 | 121 | ||
122 | if (index > carray_count(msg_tab)) | 122 | if (index > carray_count(msg_tab)) |
123 | return NULL; | 123 | return NULL; |
124 | 124 | ||
125 | msg = carray_get(msg_tab, index - 1); | 125 | msg = carray_get(msg_tab, index - 1); |
126 | 126 | ||
127 | return msg; | 127 | return msg; |
128 | } | 128 | } |
129 | 129 | ||
130 | 130 | ||
131 | 131 | ||
132 | int mailpop3_get_msg_info(mailpop3 * f, unsigned int index, | 132 | int mailpop3_get_msg_info(mailpop3 * f, unsigned int index, |
133 | struct mailpop3_msg_info ** result) | 133 | struct mailpop3_msg_info ** result) |
134 | { | 134 | { |
135 | carray * tab; | 135 | carray * tab; |
136 | struct mailpop3_msg_info * info; | 136 | struct mailpop3_msg_info * info; |
137 | 137 | ||
138 | mailpop3_list(f, &tab); | 138 | mailpop3_list(f, &tab); |
139 | 139 | ||
140 | if (tab == NULL) | 140 | if (tab == NULL) |
141 | return MAILPOP3_ERROR_BAD_STATE; | 141 | return MAILPOP3_ERROR_BAD_STATE; |
142 | 142 | ||
143 | info = mailpop3_msg_info_tab_find_msg(tab, index); | 143 | info = mailpop3_msg_info_tab_find_msg(tab, index); |
144 | if (info == NULL) | 144 | if (info == NULL) |
145 | return MAILPOP3_ERROR_NO_SUCH_MESSAGE; | 145 | return MAILPOP3_ERROR_NO_SUCH_MESSAGE; |
146 | 146 | ||
147 | * result = info; | 147 | * result = info; |
148 | 148 | ||
149 | return MAILPOP3_NO_ERROR; | 149 | return MAILPOP3_NO_ERROR; |
150 | } | 150 | } |
151 | 151 | ||
152 | 152 | ||
153 | /* | 153 | /* |
154 | mailpop3_capa | 154 | mailpop3_capa |
155 | */ | 155 | */ |
156 | 156 | ||
157 | struct mailpop3_capa * mailpop3_capa_new(char * name, clist * param) | 157 | struct mailpop3_capa * mailpop3_capa_new(char * name, clist * param) |
158 | { | 158 | { |
159 | struct mailpop3_capa * capa; | 159 | struct mailpop3_capa * capa; |
160 | 160 | ||
161 | capa = malloc(sizeof(* capa)); | 161 | capa = malloc(sizeof(* capa)); |
162 | if (capa == NULL) | 162 | if (capa == NULL) |
163 | return NULL; | 163 | return NULL; |
164 | capa->cap_name = name; | 164 | capa->cap_name = name; |
165 | capa->cap_param = param; | 165 | capa->cap_param = param; |
166 | 166 | ||
167 | return capa; | 167 | return capa; |
168 | } | 168 | } |
169 | 169 | ||
170 | 170 | ||
171 | void mailpop3_capa_free(struct mailpop3_capa * capa) | 171 | void mailpop3_capa_free(struct mailpop3_capa * capa) |
172 | { | 172 | { |
173 | clist_foreach(capa->cap_param, (clist_func) free, NULL); | 173 | clist_foreach(capa->cap_param, (clist_func) free, NULL); |
174 | clist_free(capa->cap_param); | 174 | clist_free(capa->cap_param); |
175 | free(capa->cap_name); | 175 | free(capa->cap_name); |
176 | free(capa); | 176 | free(capa); |
177 | } | 177 | } |
178 | 178 | ||
179 | /* | 179 | /* |
180 | mailpop3 structure | 180 | mailpop3 structure |
181 | */ | 181 | */ |
182 | 182 | ||
183 | mailpop3 * mailpop3_new(size_t progr_rate, progress_function * progr_fun) | 183 | mailpop3 * mailpop3_new(size_t progr_rate, progress_function * progr_fun) |
184 | { | 184 | { |
185 | mailpop3 * f; | 185 | mailpop3 * f; |
186 | 186 | ||
187 | f = malloc(sizeof(* f)); | 187 | f = malloc(sizeof(* f)); |
188 | if (f == NULL) | 188 | if (f == NULL) |
189 | goto err; | 189 | goto err; |
190 | 190 | ||
191 | f->pop3_timestamp = NULL; | 191 | f->pop3_timestamp = NULL; |
192 | f->pop3_response = NULL; | 192 | f->pop3_response = NULL; |
193 | 193 | ||
194 | f->pop3_stream = NULL; | 194 | f->pop3_stream = NULL; |
195 | 195 | ||
196 | f->pop3_progr_rate = progr_rate; | 196 | f->pop3_progr_rate = progr_rate; |
197 | f->pop3_progr_fun = progr_fun; | 197 | f->pop3_progr_fun = progr_fun; |
198 | 198 | ||
199 | f->pop3_stream_buffer = mmap_string_new(""); | 199 | f->pop3_stream_buffer = mmap_string_new(""); |
200 | if (f->pop3_stream_buffer == NULL) | 200 | if (f->pop3_stream_buffer == NULL) |
201 | goto free_f; | 201 | goto free_f; |
202 | 202 | ||
203 | f->pop3_response_buffer = mmap_string_new(""); | 203 | f->pop3_response_buffer = mmap_string_new(""); |
204 | if (f->pop3_response_buffer == NULL) | 204 | if (f->pop3_response_buffer == NULL) |
205 | goto free_stream_buffer; | 205 | goto free_stream_buffer; |
206 | 206 | ||
207 | f->pop3_msg_tab = NULL; | 207 | f->pop3_msg_tab = NULL; |
208 | f->pop3_deleted_count = 0; | 208 | f->pop3_deleted_count = 0; |
209 | f->pop3_state = POP3_STATE_DISCONNECTED; | 209 | f->pop3_state = POP3_STATE_DISCONNECTED; |
210 | 210 | ||
211 | return f; | 211 | return f; |
212 | 212 | ||
213 | free_stream_buffer: | 213 | free_stream_buffer: |
214 | mmap_string_free(f->pop3_stream_buffer); | 214 | mmap_string_free(f->pop3_stream_buffer); |
215 | free_f: | 215 | free_f: |
216 | free(f); | 216 | free(f); |
217 | err: | 217 | err: |
218 | return NULL; | 218 | return NULL; |
219 | } | 219 | } |
220 | 220 | ||
221 | 221 | ||
222 | 222 | ||
223 | void mailpop3_free(mailpop3 * f) | 223 | void mailpop3_free(mailpop3 * f) |
224 | { | 224 | { |
225 | if (f->pop3_stream) | 225 | if (f->pop3_stream) |
226 | mailpop3_quit(f); | 226 | mailpop3_quit(f); |
227 | 227 | ||
228 | mmap_string_free(f->pop3_response_buffer); | 228 | mmap_string_free(f->pop3_response_buffer); |
229 | mmap_string_free(f->pop3_stream_buffer); | 229 | mmap_string_free(f->pop3_stream_buffer); |
230 | 230 | ||
231 | free(f); | 231 | free(f); |
232 | } | 232 | } |
233 | 233 | ||
234 | 234 | ||
235 | 235 | ||
236 | 236 | ||
237 | 237 | ||
238 | 238 | ||
239 | 239 | ||
240 | 240 | ||
241 | 241 | ||
242 | 242 | ||
243 | 243 | ||
244 | /* | 244 | /* |
245 | operations on mailpop3 structure | 245 | operations on mailpop3 structure |
246 | */ | 246 | */ |
247 | 247 | ||
248 | #define RESPONSE_OK 0 | 248 | #define RESPONSE_OK 0 |
249 | #define RESPONSE_ERR -1 | 249 | #define RESPONSE_ERR -1 |
250 | 250 | ||
251 | static int send_command(mailpop3 * f, char * command); | 251 | static int send_command(mailpop3 * f, char * command); |
252 | 252 | ||
253 | static char * read_line(mailpop3 * f); | 253 | static char * read_line(mailpop3 * f); |
254 | 254 | ||
255 | static char * read_multiline(mailpop3 * f, size_t size, | 255 | static char * read_multiline(mailpop3 * f, size_t size, |
256 | MMAPString * multiline_buffer); | 256 | MMAPString * multiline_buffer); |
257 | 257 | ||
258 | static int parse_response(mailpop3 * f, char * response); | 258 | static int parse_response(mailpop3 * f, char * response); |
259 | 259 | ||
260 | 260 | ||
261 | /* get the timestamp in the connection response */ | 261 | /* get the timestamp in the connection response */ |
262 | 262 | ||
263 | #define TIMESTAMP_START '<' | 263 | #define TIMESTAMP_START '<' |
264 | #define TIMESTAMP_END '>' | 264 | #define TIMESTAMP_END '>' |
265 | 265 | ||
266 | static char * mailpop3_get_timestamp(char * response) | 266 | static char * mailpop3_get_timestamp(char * response) |
267 | { | 267 | { |
268 | char * begin_timestamp; | 268 | char * begin_timestamp; |
269 | char * end_timestamp; | 269 | char * end_timestamp; |
270 | char * timestamp; | 270 | char * timestamp; |
271 | int len_timestamp; | 271 | int len_timestamp; |
272 | 272 | ||
273 | if (response == NULL) | 273 | if (response == NULL) |
274 | return NULL; | 274 | return NULL; |
275 | 275 | ||
276 | begin_timestamp = strchr(response, TIMESTAMP_START); | 276 | begin_timestamp = strchr(response, TIMESTAMP_START); |
277 | 277 | ||
278 | end_timestamp = NULL; | 278 | end_timestamp = NULL; |
279 | if (begin_timestamp != NULL) { | 279 | if (begin_timestamp != NULL) { |
280 | end_timestamp = strchr(begin_timestamp, TIMESTAMP_END); | 280 | end_timestamp = strchr(begin_timestamp, TIMESTAMP_END); |
281 | if (end_timestamp == NULL) | 281 | if (end_timestamp == NULL) |
282 | begin_timestamp = NULL; | 282 | begin_timestamp = NULL; |
283 | } | 283 | } |
284 | 284 | ||
285 | if (!begin_timestamp) | 285 | if (!begin_timestamp) |
286 | return NULL; | 286 | return NULL; |
287 | 287 | ||
288 | len_timestamp = end_timestamp - begin_timestamp + 1; | 288 | len_timestamp = end_timestamp - begin_timestamp + 1; |
289 | 289 | ||
290 | timestamp = malloc(len_timestamp + 1); | 290 | timestamp = malloc(len_timestamp + 1); |
291 | if (timestamp == NULL) | 291 | if (timestamp == NULL) |
292 | return NULL; | 292 | return NULL; |
293 | strncpy(timestamp, begin_timestamp, len_timestamp); | 293 | strncpy(timestamp, begin_timestamp, len_timestamp); |
294 | timestamp[len_timestamp] = '\0'; | 294 | timestamp[len_timestamp] = '\0'; |
295 | 295 | ||
296 | return timestamp; | 296 | return timestamp; |
297 | } | 297 | } |
298 | 298 | ||
299 | /* | 299 | /* |
300 | connect a stream to the mailpop3 structure | 300 | connect a stream to the mailpop3 structure |
301 | */ | 301 | */ |
302 | 302 | ||
303 | int mailpop3_connect(mailpop3 * f, mailstream * s) | 303 | int mailpop3_connect(mailpop3 * f, mailstream * s) |
304 | { | 304 | { |
305 | char * response; | 305 | char * response; |
306 | int r; | 306 | int r; |
307 | char * timestamp; | 307 | char * timestamp; |
308 | 308 | ||
309 | if (f->pop3_state != POP3_STATE_DISCONNECTED) | 309 | if (f->pop3_state != POP3_STATE_DISCONNECTED) |
310 | return MAILPOP3_ERROR_BAD_STATE; | 310 | return MAILPOP3_ERROR_BAD_STATE; |
311 | 311 | ||
312 | f->pop3_stream = s; | 312 | f->pop3_stream = s; |
313 | 313 | ||
314 | response = read_line(f); | 314 | response = read_line(f); |
315 | 315 | ||
316 | r = parse_response(f, response); | 316 | r = parse_response(f, response); |
317 | if (r != RESPONSE_OK) | 317 | if (r != RESPONSE_OK) |
318 | return MAILPOP3_ERROR_UNAUTHORIZED; | 318 | return MAILPOP3_ERROR_UNAUTHORIZED; |
319 | 319 | ||
320 | f->pop3_state = POP3_STATE_AUTHORIZATION; | 320 | f->pop3_state = POP3_STATE_AUTHORIZATION; |
321 | 321 | ||
322 | timestamp = mailpop3_get_timestamp(f->pop3_response); | 322 | timestamp = mailpop3_get_timestamp(f->pop3_response); |
323 | if (timestamp != NULL) | 323 | if (timestamp != NULL) |
324 | f->pop3_timestamp = timestamp; | 324 | f->pop3_timestamp = timestamp; |
325 | 325 | ||
326 | return MAILPOP3_NO_ERROR; | 326 | return MAILPOP3_NO_ERROR; |
327 | } | 327 | } |
328 | 328 | ||
329 | 329 | ||
330 | /* | 330 | /* |
331 | disconnect from a pop3 server | 331 | disconnect from a pop3 server |
332 | */ | 332 | */ |
333 | 333 | ||
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 | ||
705 | if (f->pop3_state != POP3_STATE_TRANSACTION) | 708 | if (f->pop3_state != POP3_STATE_TRANSACTION) |
706 | return MAILPOP3_ERROR_BAD_STATE; | 709 | return MAILPOP3_ERROR_BAD_STATE; |
707 | 710 | ||
708 | msginfo = find_msg(f, index); | 711 | msginfo = find_msg(f, index); |
709 | 712 | ||
710 | if (msginfo == NULL) { | 713 | if (msginfo == NULL) { |
711 | f->pop3_response = NULL; | 714 | f->pop3_response = NULL; |
712 | return MAILPOP3_ERROR_NO_SUCH_MESSAGE; | 715 | return MAILPOP3_ERROR_NO_SUCH_MESSAGE; |
713 | } | 716 | } |
714 | 717 | ||
715 | snprintf(command, POP3_STRING_SIZE, "RETR %i\r\n", index); | 718 | snprintf(command, POP3_STRING_SIZE, "RETR %i\r\n", index); |
716 | r = send_command(f, command); | 719 | r = send_command(f, command); |
717 | if (r == -1) | 720 | if (r == -1) |
718 | return MAILPOP3_ERROR_STREAM; | 721 | return MAILPOP3_ERROR_STREAM; |
719 | 722 | ||
720 | return mailpop3_get_content(f, msginfo, result, result_len); | 723 | return mailpop3_get_content(f, msginfo, result, result_len); |
721 | } | 724 | } |
722 | 725 | ||
723 | int mailpop3_top(mailpop3 * f, unsigned int index, | 726 | int mailpop3_top(mailpop3 * f, unsigned int index, |
724 | unsigned int count, char ** result, | 727 | unsigned int count, char ** result, |
725 | size_t * result_len) | 728 | size_t * result_len) |
726 | { | 729 | { |
727 | char command[POP3_STRING_SIZE]; | 730 | char command[POP3_STRING_SIZE]; |
728 | struct mailpop3_msg_info * msginfo; | 731 | struct mailpop3_msg_info * msginfo; |
729 | int r; | 732 | int r; |
730 | 733 | ||
731 | if (f->pop3_state != POP3_STATE_TRANSACTION) | 734 | if (f->pop3_state != POP3_STATE_TRANSACTION) |
732 | return MAILPOP3_ERROR_BAD_STATE; | 735 | return MAILPOP3_ERROR_BAD_STATE; |
733 | 736 | ||
734 | msginfo = find_msg(f, index); | 737 | msginfo = find_msg(f, index); |
735 | 738 | ||
736 | if (msginfo == NULL) { | 739 | if (msginfo == NULL) { |
737 | f->pop3_response = NULL; | 740 | f->pop3_response = NULL; |
738 | return MAILPOP3_ERROR_NO_SUCH_MESSAGE; | 741 | return MAILPOP3_ERROR_NO_SUCH_MESSAGE; |
739 | } | 742 | } |
740 | 743 | ||
741 | snprintf(command, POP3_STRING_SIZE, "TOP %i %i\r\n", index, count); | 744 | snprintf(command, POP3_STRING_SIZE, "TOP %i %i\r\n", index, count); |
742 | r = send_command(f, command); | 745 | r = send_command(f, command); |
743 | if (r == -1) | 746 | if (r == -1) |
744 | return MAILPOP3_ERROR_STREAM; | 747 | return MAILPOP3_ERROR_STREAM; |
745 | 748 | ||
746 | return mailpop3_get_content(f, msginfo, result, result_len); | 749 | return mailpop3_get_content(f, msginfo, result, result_len); |
747 | } | 750 | } |
748 | 751 | ||
749 | int mailpop3_dele(mailpop3 * f, unsigned int index) | 752 | int mailpop3_dele(mailpop3 * f, unsigned int index) |
750 | { | 753 | { |
751 | char command[POP3_STRING_SIZE]; | 754 | char command[POP3_STRING_SIZE]; |
752 | struct mailpop3_msg_info * msginfo; | 755 | struct mailpop3_msg_info * msginfo; |
753 | char * response; | 756 | char * response; |
754 | int r; | 757 | int r; |
755 | 758 | ||
756 | if (f->pop3_state != POP3_STATE_TRANSACTION) | 759 | if (f->pop3_state != POP3_STATE_TRANSACTION) |
757 | return MAILPOP3_ERROR_BAD_STATE; | 760 | return MAILPOP3_ERROR_BAD_STATE; |
758 | 761 | ||
759 | msginfo = find_msg(f, index); | 762 | msginfo = find_msg(f, index); |
760 | 763 | ||
761 | if (msginfo == NULL) { | 764 | if (msginfo == NULL) { |
762 | f->pop3_response = NULL; | 765 | f->pop3_response = NULL; |
763 | return MAILPOP3_ERROR_NO_SUCH_MESSAGE; | 766 | return MAILPOP3_ERROR_NO_SUCH_MESSAGE; |
764 | } | 767 | } |
765 | 768 | ||
766 | snprintf(command, POP3_STRING_SIZE, "DELE %i\r\n", index); | 769 | snprintf(command, POP3_STRING_SIZE, "DELE %i\r\n", index); |
767 | r = send_command(f, command); | 770 | r = send_command(f, command); |
768 | if (r == -1) | 771 | if (r == -1) |
769 | return MAILPOP3_ERROR_STREAM; | 772 | return MAILPOP3_ERROR_STREAM; |
770 | 773 | ||
771 | response = read_line(f); | 774 | response = read_line(f); |
772 | if (response == NULL) | 775 | if (response == NULL) |
773 | return MAILPOP3_ERROR_STREAM; | 776 | return MAILPOP3_ERROR_STREAM; |
774 | r = parse_response(f, response); | 777 | r = parse_response(f, response); |
775 | if (r != RESPONSE_OK) | 778 | if (r != RESPONSE_OK) |
776 | return MAILPOP3_ERROR_NO_SUCH_MESSAGE; | 779 | return MAILPOP3_ERROR_NO_SUCH_MESSAGE; |
777 | 780 | ||
778 | msginfo->msg_deleted = TRUE; | 781 | msginfo->msg_deleted = TRUE; |
779 | f->pop3_deleted_count ++; | 782 | f->pop3_deleted_count ++; |
780 | 783 | ||
781 | return MAILPOP3_NO_ERROR; | 784 | return MAILPOP3_NO_ERROR; |
782 | } | 785 | } |
783 | 786 | ||
784 | int mailpop3_noop(mailpop3 * f) | 787 | int mailpop3_noop(mailpop3 * f) |
785 | { | 788 | { |
786 | char command[POP3_STRING_SIZE]; | 789 | char command[POP3_STRING_SIZE]; |
787 | char * response; | 790 | char * response; |
788 | int r; | 791 | int r; |
789 | 792 | ||
790 | if (f->pop3_state != POP3_STATE_TRANSACTION) | 793 | if (f->pop3_state != POP3_STATE_TRANSACTION) |
791 | return MAILPOP3_ERROR_BAD_STATE; | 794 | return MAILPOP3_ERROR_BAD_STATE; |
792 | 795 | ||
793 | snprintf(command, POP3_STRING_SIZE, "NOOP\r\n"); | 796 | snprintf(command, POP3_STRING_SIZE, "NOOP\r\n"); |
794 | r = send_command(f, command); | 797 | r = send_command(f, command); |
795 | if (r == -1) | 798 | if (r == -1) |
796 | return MAILPOP3_ERROR_STREAM; | 799 | return MAILPOP3_ERROR_STREAM; |
797 | 800 | ||
798 | response = read_line(f); | 801 | response = read_line(f); |
799 | if (response == NULL) | 802 | if (response == NULL) |
800 | return MAILPOP3_ERROR_STREAM; | 803 | return MAILPOP3_ERROR_STREAM; |
801 | parse_response(f, response); | 804 | parse_response(f, response); |
802 | 805 | ||
803 | return MAILPOP3_NO_ERROR; | 806 | return MAILPOP3_NO_ERROR; |
804 | } | 807 | } |
805 | 808 | ||
806 | int mailpop3_rset(mailpop3 * f) | 809 | int mailpop3_rset(mailpop3 * f) |
807 | { | 810 | { |
808 | char command[POP3_STRING_SIZE]; | 811 | char command[POP3_STRING_SIZE]; |
809 | char * response; | 812 | char * response; |
810 | int r; | 813 | int r; |
811 | 814 | ||
812 | if (f->pop3_state != POP3_STATE_TRANSACTION) | 815 | if (f->pop3_state != POP3_STATE_TRANSACTION) |
813 | return MAILPOP3_ERROR_BAD_STATE; | 816 | return MAILPOP3_ERROR_BAD_STATE; |
814 | 817 | ||
815 | snprintf(command, POP3_STRING_SIZE, "RSET\r\n"); | 818 | snprintf(command, POP3_STRING_SIZE, "RSET\r\n"); |
816 | r = send_command(f, command); | 819 | r = send_command(f, command); |
817 | if (r == -1) | 820 | if (r == -1) |
818 | return MAILPOP3_ERROR_STREAM; | 821 | return MAILPOP3_ERROR_STREAM; |
819 | 822 | ||
820 | response = read_line(f); | 823 | response = read_line(f); |
821 | if (response == NULL) | 824 | if (response == NULL) |
822 | return MAILPOP3_ERROR_STREAM; | 825 | return MAILPOP3_ERROR_STREAM; |
823 | parse_response(f, response); | 826 | parse_response(f, response); |
824 | 827 | ||
825 | if (f->pop3_msg_tab != NULL) { | 828 | if (f->pop3_msg_tab != NULL) { |
826 | mailpop3_msg_info_tab_reset(f->pop3_msg_tab); | 829 | mailpop3_msg_info_tab_reset(f->pop3_msg_tab); |
827 | f->pop3_deleted_count = 0; | 830 | f->pop3_deleted_count = 0; |
828 | } | 831 | } |
829 | 832 | ||
830 | return MAILPOP3_NO_ERROR; | 833 | return MAILPOP3_NO_ERROR; |
831 | } | 834 | } |
832 | 835 | ||
833 | 836 | ||
834 | 837 | ||
835 | static int read_capa_resp(mailpop3 * f, clist ** result); | 838 | static int read_capa_resp(mailpop3 * f, clist ** result); |
836 | 839 | ||
837 | int mailpop3_capa(mailpop3 * f, clist ** result) | 840 | int mailpop3_capa(mailpop3 * f, clist ** result) |
838 | { | 841 | { |
839 | clist * capa_list; | 842 | clist * capa_list; |
840 | char command[POP3_STRING_SIZE]; | 843 | char command[POP3_STRING_SIZE]; |
841 | int r; | 844 | int r; |
842 | char * response; | 845 | char * response; |
843 | 846 | ||
844 | snprintf(command, POP3_STRING_SIZE, "CAPA\r\n"); | 847 | snprintf(command, POP3_STRING_SIZE, "CAPA\r\n"); |
845 | r = send_command(f, command); | 848 | r = send_command(f, command); |
846 | if (r == -1) | 849 | if (r == -1) |
847 | return MAILPOP3_ERROR_STREAM; | 850 | return MAILPOP3_ERROR_STREAM; |
848 | 851 | ||
849 | response = read_line(f); | 852 | response = read_line(f); |
850 | if (response == NULL) | 853 | if (response == NULL) |
851 | return MAILPOP3_ERROR_STREAM; | 854 | return MAILPOP3_ERROR_STREAM; |
852 | r = parse_response(f, response); | 855 | r = parse_response(f, response); |
853 | 856 | ||
854 | if (r != RESPONSE_OK) | 857 | if (r != RESPONSE_OK) |
855 | return MAILPOP3_ERROR_CAPA_NOT_SUPPORTED; | 858 | return MAILPOP3_ERROR_CAPA_NOT_SUPPORTED; |
856 | 859 | ||
857 | r = read_capa_resp(f, &capa_list); | 860 | r = read_capa_resp(f, &capa_list); |
858 | if (r != MAILPOP3_NO_ERROR) | 861 | if (r != MAILPOP3_NO_ERROR) |
859 | return r; | 862 | return r; |
860 | 863 | ||
861 | * result = capa_list; | 864 | * result = capa_list; |
862 | 865 | ||
863 | return MAILPOP3_NO_ERROR; | 866 | return MAILPOP3_NO_ERROR; |
864 | } | 867 | } |
865 | 868 | ||
866 | void mailpop3_capa_resp_free(clist * capa_list) | 869 | void mailpop3_capa_resp_free(clist * capa_list) |
867 | { | 870 | { |
868 | clist_foreach(capa_list, (clist_func) mailpop3_capa_free, NULL); | 871 | clist_foreach(capa_list, (clist_func) mailpop3_capa_free, NULL); |
869 | clist_free(capa_list); | 872 | clist_free(capa_list); |
870 | } | 873 | } |
871 | 874 | ||
872 | int mailpop3_stls(mailpop3 * f) | 875 | int mailpop3_stls(mailpop3 * f) |
873 | { | 876 | { |
874 | char command[POP3_STRING_SIZE]; | 877 | char command[POP3_STRING_SIZE]; |
875 | int r; | 878 | int r; |
876 | char * response; | 879 | char * response; |
877 | 880 | ||
878 | snprintf(command, POP3_STRING_SIZE, "STLS\r\n"); | 881 | snprintf(command, POP3_STRING_SIZE, "STLS\r\n"); |
879 | r = send_command(f, command); | 882 | r = send_command(f, command); |
880 | if (r == -1) | 883 | if (r == -1) |
881 | return MAILPOP3_ERROR_STREAM; | 884 | return MAILPOP3_ERROR_STREAM; |
882 | 885 | ||
883 | response = read_line(f); | 886 | response = read_line(f); |
884 | if (response == NULL) | 887 | if (response == NULL) |
885 | return MAILPOP3_ERROR_STREAM; | 888 | return MAILPOP3_ERROR_STREAM; |
886 | r = parse_response(f, response); | 889 | r = parse_response(f, response); |
887 | 890 | ||
888 | if (r != RESPONSE_OK) | 891 | if (r != RESPONSE_OK) |
889 | return MAILPOP3_ERROR_STLS_NOT_SUPPORTED; | 892 | return MAILPOP3_ERROR_STLS_NOT_SUPPORTED; |
890 | 893 | ||
891 | return MAILPOP3_NO_ERROR; | 894 | return MAILPOP3_NO_ERROR; |
892 | } | 895 | } |
893 | 896 | ||
894 | 897 | ||
895 | 898 | ||
896 | 899 | ||
897 | 900 | ||
898 | 901 | ||
899 | 902 | ||
900 | 903 | ||
901 | 904 | ||
902 | 905 | ||
903 | 906 | ||
904 | 907 | ||
905 | 908 | ||
906 | 909 | ||
907 | 910 | ||
908 | 911 | ||
909 | 912 | ||
910 | 913 | ||
911 | 914 | ||
912 | 915 | ||
913 | 916 | ||
914 | 917 | ||
915 | 918 | ||
916 | 919 | ||
917 | #define RESP_OK_STR "+OK" | 920 | #define RESP_OK_STR "+OK" |
918 | #define RESP_ERR_STR "-ERR" | 921 | #define RESP_ERR_STR "-ERR" |
919 | 922 | ||
920 | 923 | ||
921 | static int parse_space(char ** line) | 924 | static int parse_space(char ** line) |
922 | { | 925 | { |
923 | char * p; | 926 | char * p; |
924 | 927 | ||
925 | p = * line; | 928 | p = * line; |
926 | 929 | ||
927 | while ((* p == ' ') || (* p == '\t')) | 930 | while ((* p == ' ') || (* p == '\t')) |
928 | p ++; | 931 | p ++; |
929 | 932 | ||
930 | if (p != * line) { | 933 | if (p != * line) { |
931 | * line = p; | 934 | * line = p; |
932 | return TRUE; | 935 | return TRUE; |
933 | } | 936 | } |
934 | else | 937 | else |
935 | return FALSE; | 938 | return FALSE; |
936 | } | 939 | } |
937 | 940 | ||
938 | static char * cut_token(char * line) | 941 | static char * cut_token(char * line) |
939 | { | 942 | { |
940 | char * p; | 943 | char * p; |
941 | char * p_tab; | 944 | char * p_tab; |
942 | char * p_space; | 945 | char * p_space; |
943 | 946 | ||
944 | p = line; | 947 | p = line; |
945 | 948 | ||
946 | p_space = strchr(line, ' '); | 949 | p_space = strchr(line, ' '); |
947 | p_tab = strchr(line, '\t'); | 950 | p_tab = strchr(line, '\t'); |
948 | if (p_tab == NULL) | 951 | if (p_tab == NULL) |
949 | p = p_space; | 952 | p = p_space; |
950 | else if (p_space == NULL) | 953 | else if (p_space == NULL) |
951 | p = p_tab; | 954 | p = p_tab; |
952 | else { | 955 | else { |
953 | if (p_tab < p_space) | 956 | if (p_tab < p_space) |
954 | p = p_tab; | 957 | p = p_tab; |
955 | else | 958 | else |
956 | p = p_space; | 959 | p = p_space; |
957 | } | 960 | } |
958 | if (p == NULL) | 961 | if (p == NULL) |
959 | return NULL; | 962 | return NULL; |
960 | * p = 0; | 963 | * p = 0; |
961 | p ++; | 964 | p ++; |
962 | 965 | ||
963 | return p; | 966 | return p; |
964 | } | 967 | } |
965 | 968 | ||
966 | 969 | ||
967 | static int parse_response(mailpop3 * f, char * response) | 970 | static int parse_response(mailpop3 * f, char * response) |
968 | { | 971 | { |
969 | char * msg; | 972 | char * msg; |
970 | 973 | ||
971 | if (response == NULL) { | 974 | if (response == NULL) { |
972 | f->pop3_response = NULL; | 975 | f->pop3_response = NULL; |
973 | return RESPONSE_ERR; | 976 | return RESPONSE_ERR; |
974 | } | 977 | } |
975 | 978 | ||
976 | if (strncmp(response, RESP_OK_STR, strlen(RESP_OK_STR)) == 0) { | 979 | if (strncmp(response, RESP_OK_STR, strlen(RESP_OK_STR)) == 0) { |
977 | 980 | ||
978 | if (response[strlen(RESP_OK_STR)] == ' ') | 981 | if (response[strlen(RESP_OK_STR)] == ' ') |
979 | msg = response + strlen(RESP_OK_STR) + 1; | 982 | msg = response + strlen(RESP_OK_STR) + 1; |
980 | else | 983 | else |
981 | msg = response + strlen(RESP_OK_STR); | 984 | msg = response + strlen(RESP_OK_STR); |
982 | 985 | ||
983 | if (mmap_string_assign(f->pop3_response_buffer, msg)) | 986 | if (mmap_string_assign(f->pop3_response_buffer, msg)) |
984 | f->pop3_response = f->pop3_response_buffer->str; | 987 | f->pop3_response = f->pop3_response_buffer->str; |
985 | else | 988 | else |
986 | f->pop3_response = NULL; | 989 | f->pop3_response = NULL; |
987 | 990 | ||
988 | return RESPONSE_OK; | 991 | return RESPONSE_OK; |
989 | } | 992 | } |
990 | else if (strncmp(response, RESP_ERR_STR, strlen(RESP_ERR_STR)) == 0) { | 993 | else if (strncmp(response, RESP_ERR_STR, strlen(RESP_ERR_STR)) == 0) { |
991 | 994 | ||
992 | if (response[strlen(RESP_ERR_STR)] == ' ') | 995 | if (response[strlen(RESP_ERR_STR)] == ' ') |
993 | msg = response + strlen(RESP_ERR_STR) + 1; | 996 | msg = response + strlen(RESP_ERR_STR) + 1; |
994 | else | 997 | else |
995 | msg = response + strlen(RESP_ERR_STR); | 998 | msg = response + strlen(RESP_ERR_STR); |
996 | 999 | ||
997 | if (mmap_string_assign(f->pop3_response_buffer, msg)) | 1000 | if (mmap_string_assign(f->pop3_response_buffer, msg)) |
998 | f->pop3_response = f->pop3_response_buffer->str; | 1001 | f->pop3_response = f->pop3_response_buffer->str; |
999 | else | 1002 | else |
1000 | f->pop3_response = NULL; | 1003 | f->pop3_response = NULL; |
1001 | } | 1004 | } |
1002 | 1005 | ||
1003 | f->pop3_response = NULL; | 1006 | f->pop3_response = NULL; |
1004 | return RESPONSE_ERR; | 1007 | return RESPONSE_ERR; |
1005 | } | 1008 | } |
1006 | 1009 | ||
1007 | 1010 | ||
1008 | 1011 | ||
1009 | 1012 | ||
1010 | 1013 | ||
1011 | 1014 | ||
1012 | 1015 | ||
1013 | static int read_list(mailpop3 * f, carray ** result) | 1016 | static int read_list(mailpop3 * f, carray ** result) |
1014 | { | 1017 | { |
1015 | unsigned int index; | 1018 | unsigned int index; |
1016 | uint32_t size; | 1019 | uint32_t size; |
1017 | carray * msg_tab; | 1020 | carray * msg_tab; |
1018 | struct mailpop3_msg_info * msg; | 1021 | struct mailpop3_msg_info * msg; |
1019 | char * line; | 1022 | char * line; |
1020 | 1023 | ||
1021 | msg_tab = carray_new(128); | 1024 | msg_tab = carray_new(128); |
1022 | if (msg_tab == NULL) | 1025 | if (msg_tab == NULL) |
1023 | goto err; | 1026 | goto err; |
1024 | 1027 | ||
1025 | while (1) { | 1028 | while (1) { |
1026 | line = read_line(f); | 1029 | line = read_line(f); |
1027 | if (line == NULL) | 1030 | if (line == NULL) |
1028 | goto free_list; | 1031 | goto free_list; |
1029 | 1032 | ||
1030 | if (mailstream_is_end_multiline(line)) | 1033 | if (mailstream_is_end_multiline(line)) |
1031 | break; | 1034 | break; |
1032 | 1035 | ||
1033 | index = strtol(line, &line, 10); | 1036 | index = strtol(line, &line, 10); |
1034 | 1037 | ||
1035 | if (!parse_space(&line)) | 1038 | if (!parse_space(&line)) |
1036 | continue; | 1039 | continue; |
1037 | 1040 | ||
1038 | size = strtol(line, &line, 10); | 1041 | size = strtol(line, &line, 10); |
1039 | 1042 | ||
1040 | msg = mailpop3_msg_info_new(index, size, NULL); | 1043 | msg = mailpop3_msg_info_new(index, size, NULL); |
1041 | if (msg == NULL) | 1044 | if (msg == NULL) |
1042 | goto free_list; | 1045 | goto free_list; |
1043 | 1046 | ||
1044 | if (carray_count(msg_tab) < index) { | 1047 | if (carray_count(msg_tab) < index) { |
1045 | int r; | 1048 | int r; |
1046 | 1049 | ||
1047 | r = carray_set_size(msg_tab, index); | 1050 | r = carray_set_size(msg_tab, index); |
1048 | if (r == -1) | 1051 | if (r == -1) |
1049 | goto free_list; | 1052 | goto free_list; |
1050 | } | 1053 | } |
1051 | 1054 | ||
1052 | carray_set(msg_tab, index - 1, msg); | 1055 | carray_set(msg_tab, index - 1, msg); |
1053 | } | 1056 | } |
1054 | 1057 | ||
1055 | * result = msg_tab; | 1058 | * result = msg_tab; |
1056 | 1059 | ||
1057 | return MAILPOP3_NO_ERROR; | 1060 | return MAILPOP3_NO_ERROR; |
1058 | 1061 | ||
1059 | free_list: | 1062 | free_list: |
1060 | mailpop3_msg_info_tab_free(msg_tab); | 1063 | mailpop3_msg_info_tab_free(msg_tab); |
1061 | err: | 1064 | err: |
1062 | return MAILPOP3_ERROR_STREAM; | 1065 | return MAILPOP3_ERROR_STREAM; |
1063 | } | 1066 | } |
1064 | 1067 | ||
1065 | 1068 | ||
1066 | 1069 | ||
1067 | static int read_uidl(mailpop3 * f, carray * msg_tab) | 1070 | static int read_uidl(mailpop3 * f, carray * msg_tab) |
1068 | { | 1071 | { |
1069 | unsigned int index; | 1072 | unsigned int index; |
1070 | struct mailpop3_msg_info * msg; | 1073 | struct mailpop3_msg_info * msg; |
1071 | char * line; | 1074 | char * line; |
1072 | 1075 | ||
1073 | while (1) { | 1076 | while (1) { |
1074 | char * uidl; | 1077 | char * uidl; |
1075 | 1078 | ||
1076 | line = read_line(f); | 1079 | line = read_line(f); |
1077 | if (line == NULL) | 1080 | if (line == NULL) |
1078 | goto err; | 1081 | goto err; |
1079 | 1082 | ||
1080 | if (mailstream_is_end_multiline(line)) | 1083 | if (mailstream_is_end_multiline(line)) |
1081 | break; | 1084 | break; |
1082 | 1085 | ||
1083 | index = strtol(line, &line, 10); | 1086 | index = strtol(line, &line, 10); |
1084 | 1087 | ||
1085 | if (!parse_space(&line)) | 1088 | if (!parse_space(&line)) |
1086 | continue; | 1089 | continue; |
1087 | 1090 | ||
1088 | uidl = strdup(line); | 1091 | uidl = strdup(line); |
1089 | if (uidl == NULL) | 1092 | if (uidl == NULL) |
1090 | continue; | 1093 | continue; |
1091 | 1094 | ||
1092 | if (index > carray_count(msg_tab)) { | 1095 | if (index > carray_count(msg_tab)) { |
1093 | free(uidl); | 1096 | free(uidl); |
1094 | continue; | 1097 | continue; |
1095 | } | 1098 | } |
1096 | 1099 | ||
1097 | msg = carray_get(msg_tab, index - 1); | 1100 | msg = carray_get(msg_tab, index - 1); |
1098 | if (msg == NULL) { | 1101 | if (msg == NULL) { |
1099 | free(uidl); | 1102 | free(uidl); |
1100 | continue; | 1103 | continue; |
1101 | } | 1104 | } |
1102 | 1105 | ||
1103 | msg->msg_uidl = uidl; | 1106 | msg->msg_uidl = uidl; |
1104 | } | 1107 | } |
1105 | 1108 | ||
1106 | return MAILPOP3_NO_ERROR; | 1109 | return MAILPOP3_NO_ERROR; |
1107 | 1110 | ||
1108 | err: | 1111 | err: |
1109 | return MAILPOP3_ERROR_STREAM; | 1112 | return MAILPOP3_ERROR_STREAM; |
1110 | } | 1113 | } |
1111 | 1114 | ||
1112 | 1115 | ||
1113 | 1116 | ||
1114 | static int read_capa_resp(mailpop3 * f, clist ** result) | 1117 | static int read_capa_resp(mailpop3 * f, clist ** result) |
1115 | { | 1118 | { |
1116 | char * line; | 1119 | char * line; |
1117 | int res; | 1120 | int res; |
1118 | clist * list; | 1121 | clist * list; |
1119 | int r; | 1122 | int r; |
1120 | char * name; | 1123 | char * name; |
1121 | clist * param_list; | 1124 | clist * param_list; |
1122 | 1125 | ||
1123 | list = clist_new(); | 1126 | list = clist_new(); |
1124 | if (list == NULL) { | 1127 | if (list == NULL) { |
1125 | res = MAILPOP3_NO_ERROR; | 1128 | res = MAILPOP3_NO_ERROR; |
1126 | goto err; | 1129 | goto err; |
1127 | } | 1130 | } |
1128 | 1131 | ||
1129 | while (1) { | 1132 | while (1) { |
1130 | char * next_token; | 1133 | char * next_token; |
1131 | char * param; | 1134 | char * param; |
1132 | struct mailpop3_capa * capa; | 1135 | struct mailpop3_capa * capa; |
1133 | 1136 | ||
1134 | line = read_line(f); | 1137 | line = read_line(f); |
1135 | if (line == NULL) { | 1138 | if (line == NULL) { |
1136 | res = MAILPOP3_ERROR_STREAM; | 1139 | res = MAILPOP3_ERROR_STREAM; |
1137 | goto free_list; | 1140 | goto free_list; |
1138 | } | 1141 | } |
1139 | 1142 | ||
1140 | if (mailstream_is_end_multiline(line)) | 1143 | if (mailstream_is_end_multiline(line)) |
1141 | break; | 1144 | break; |
1142 | 1145 | ||
1143 | next_token = cut_token(line); | 1146 | next_token = cut_token(line); |
1144 | name = strdup(line); | 1147 | name = strdup(line); |
1145 | if (name == NULL) { | 1148 | if (name == NULL) { |
1146 | res = MAILPOP3_ERROR_MEMORY; | 1149 | res = MAILPOP3_ERROR_MEMORY; |
1147 | goto free_list; | 1150 | goto free_list; |
1148 | } | 1151 | } |
1149 | 1152 | ||
1150 | param_list = clist_new(); | 1153 | param_list = clist_new(); |
1151 | if (param_list == NULL) { | 1154 | if (param_list == NULL) { |
1152 | res = MAILPOP3_ERROR_MEMORY; | 1155 | res = MAILPOP3_ERROR_MEMORY; |
1153 | goto free_capa_name; | 1156 | goto free_capa_name; |
1154 | } | 1157 | } |
1155 | 1158 | ||
1156 | while (next_token != NULL) { | 1159 | while (next_token != NULL) { |
1157 | line = next_token; | 1160 | line = next_token; |
1158 | next_token = cut_token(line); | 1161 | next_token = cut_token(line); |
1159 | param = strdup(line); | 1162 | param = strdup(line); |
1160 | if (param == NULL) { | 1163 | if (param == NULL) { |
1161 | res = MAILPOP3_ERROR_MEMORY; | 1164 | res = MAILPOP3_ERROR_MEMORY; |
1162 | goto free_param_list; | 1165 | goto free_param_list; |
1163 | } | 1166 | } |
1164 | r = clist_append(param_list, param); | 1167 | r = clist_append(param_list, param); |
1165 | if (r < 0) { | 1168 | if (r < 0) { |
1166 | free(param); | 1169 | free(param); |
1167 | res = MAILPOP3_ERROR_MEMORY; | 1170 | res = MAILPOP3_ERROR_MEMORY; |
1168 | goto free_param_list; | 1171 | goto free_param_list; |
1169 | } | 1172 | } |
1170 | } | 1173 | } |
1171 | 1174 | ||
1172 | capa = mailpop3_capa_new(name, param_list); | 1175 | capa = mailpop3_capa_new(name, param_list); |
1173 | if (capa == NULL) { | 1176 | if (capa == NULL) { |
1174 | res = MAILPOP3_ERROR_MEMORY; | 1177 | res = MAILPOP3_ERROR_MEMORY; |
1175 | goto free_param_list; | 1178 | goto free_param_list; |
1176 | } | 1179 | } |
1177 | 1180 | ||
1178 | r = clist_append(list, capa); | 1181 | r = clist_append(list, capa); |
1179 | if (r < 0) { | 1182 | if (r < 0) { |
1180 | mailpop3_capa_free(capa); | 1183 | mailpop3_capa_free(capa); |
1181 | res = MAILPOP3_ERROR_MEMORY; | 1184 | res = MAILPOP3_ERROR_MEMORY; |
1182 | goto free_list; | 1185 | goto free_list; |
1183 | } | 1186 | } |
1184 | } | 1187 | } |
1185 | 1188 | ||
1186 | * result = list; | 1189 | * result = list; |
1187 | 1190 | ||
1188 | return MAILPOP3_NO_ERROR; | 1191 | return MAILPOP3_NO_ERROR; |
1189 | 1192 | ||
1190 | free_param_list: | 1193 | free_param_list: |
1191 | clist_foreach(param_list, (clist_func) free, NULL); | 1194 | clist_foreach(param_list, (clist_func) free, NULL); |
1192 | clist_free(param_list); | 1195 | clist_free(param_list); |
1193 | free_capa_name: | 1196 | free_capa_name: |
1194 | free(name); | 1197 | free(name); |
1195 | free_list: | 1198 | free_list: |
1196 | clist_foreach(list, (clist_func) mailpop3_capa_free, NULL); | 1199 | clist_foreach(list, (clist_func) mailpop3_capa_free, NULL); |
1197 | clist_free(list); | 1200 | clist_free(list); |
1198 | err: | 1201 | err: |
1199 | return res; | 1202 | return res; |
1200 | } | 1203 | } |
1201 | 1204 | ||
1202 | 1205 | ||
1203 | 1206 | ||
1204 | static char * read_line(mailpop3 * f) | 1207 | static char * read_line(mailpop3 * f) |
1205 | { | 1208 | { |
1206 | return mailstream_read_line_remove_eol(f->pop3_stream, f->pop3_stream_buffer); | 1209 | return mailstream_read_line_remove_eol(f->pop3_stream, f->pop3_stream_buffer); |
1207 | } | 1210 | } |
1208 | 1211 | ||
1209 | static char * read_multiline(mailpop3 * f, size_t size, | 1212 | static char * read_multiline(mailpop3 * f, size_t size, |
1210 | MMAPString * multiline_buffer) | 1213 | MMAPString * multiline_buffer) |
1211 | { | 1214 | { |
1212 | return mailstream_read_multiline(f->pop3_stream, size, | 1215 | return mailstream_read_multiline(f->pop3_stream, size, |
1213 | f->pop3_stream_buffer, multiline_buffer, | 1216 | f->pop3_stream_buffer, multiline_buffer, |
1214 | f->pop3_progr_rate, f->pop3_progr_fun); | 1217 | f->pop3_progr_rate, f->pop3_progr_fun); |
1215 | } | 1218 | } |
1216 | 1219 | ||
1217 | static int send_command(mailpop3 * f, char * command) | 1220 | static int send_command(mailpop3 * f, char * command) |
1218 | { | 1221 | { |
1219 | ssize_t r; | 1222 | ssize_t r; |
1220 | 1223 | ||
1221 | r = mailstream_write(f->pop3_stream, command, strlen(command)); | 1224 | r = mailstream_write(f->pop3_stream, command, strlen(command)); |
1222 | if (r == -1) | 1225 | if (r == -1) |
1223 | return -1; | 1226 | return -1; |
1224 | 1227 | ||
1225 | r = mailstream_flush(f->pop3_stream); | 1228 | r = mailstream_flush(f->pop3_stream); |
1226 | if (r == -1) | 1229 | if (r == -1) |
1227 | return -1; | 1230 | return -1; |
1228 | 1231 | ||
1229 | return 0; | 1232 | return 0; |
1230 | } | 1233 | } |