Diffstat (limited to 'kmicromail/libetpan/tools/mailstream_helper.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | kmicromail/libetpan/tools/mailstream_helper.c | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/kmicromail/libetpan/tools/mailstream_helper.c b/kmicromail/libetpan/tools/mailstream_helper.c new file mode 100644 index 0000000..146f955 --- a/dev/null +++ b/kmicromail/libetpan/tools/mailstream_helper.c | |||
@@ -0,0 +1,383 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2002 - DINH Viet Hoa | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
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 | ||
17 | * from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
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 | ||
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 | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * $Id$ | ||
34 | */ | ||
35 | |||
36 | #include "mailstream_helper.h" | ||
37 | #include <string.h> | ||
38 | #include <stdio.h> | ||
39 | #include "mail.h" | ||
40 | |||
41 | static void remove_trailing_eol(MMAPString * mmapstr) | ||
42 | { | ||
43 | if (mmapstr->str[mmapstr->len - 1] == '\n') { | ||
44 | mmapstr->len --; | ||
45 | mmapstr->str[mmapstr->len] = '\0'; | ||
46 | } | ||
47 | if (mmapstr->str[mmapstr->len - 1] == '\r') { | ||
48 | mmapstr->len --; | ||
49 | mmapstr->str[mmapstr->len] = '\0'; | ||
50 | } | ||
51 | } | ||
52 | |||
53 | char * mailstream_read_line(mailstream * stream, MMAPString * line) | ||
54 | { | ||
55 | if (mmap_string_assign(line, "") == NULL) | ||
56 | return NULL; | ||
57 | |||
58 | return mailstream_read_line_append(stream, line); | ||
59 | } | ||
60 | |||
61 | static char * mailstream_read_len_append(mailstream * stream, | ||
62 | MMAPString * line, | ||
63 | size_t i) | ||
64 | { | ||
65 | size_t cur_size; | ||
66 | |||
67 | cur_size = line->len; | ||
68 | if (mmap_string_set_size(line, line->len + i) == NULL) | ||
69 | return NULL; | ||
70 | if (mailstream_read(stream, line->str + cur_size, i) < 0) | ||
71 | return NULL; | ||
72 | return line->str; | ||
73 | } | ||
74 | |||
75 | char * mailstream_read_line_append(mailstream * stream, MMAPString * line) | ||
76 | { | ||
77 | if (stream == NULL) | ||
78 | return NULL; | ||
79 | |||
80 | do { | ||
81 | if (stream->read_buffer_len > 0) { | ||
82 | size_t i; | ||
83 | |||
84 | i = 0; | ||
85 | while (i < stream->read_buffer_len) { | ||
86 | if (stream->read_buffer[i] == '\n') | ||
87 | return mailstream_read_len_append(stream, line, i + 1); | ||
88 | i++; | ||
89 | } | ||
90 | if (mailstream_read_len_append(stream, line, | ||
91 | stream->read_buffer_len) == NULL) | ||
92 | return NULL; | ||
93 | } | ||
94 | else { | ||
95 | ssize_t r; | ||
96 | |||
97 | r = mailstream_feed_read_buffer(stream); | ||
98 | if (r == -1) | ||
99 | return NULL; | ||
100 | |||
101 | if (r == 0) | ||
102 | break; | ||
103 | } | ||
104 | } | ||
105 | while (1); | ||
106 | |||
107 | return line->str; | ||
108 | } | ||
109 | |||
110 | char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line) | ||
111 | { | ||
112 | if (!mailstream_read_line(stream, line)) | ||
113 | return NULL; | ||
114 | |||
115 | remove_trailing_eol(line); | ||
116 | |||
117 | return line->str; | ||
118 | } | ||
119 | |||
120 | int mailstream_is_end_multiline(const char * line) | ||
121 | { | ||
122 | if (line[0] != '.') | ||
123 | return FALSE; | ||
124 | if (line[1] != 0) | ||
125 | return FALSE; | ||
126 | return TRUE; | ||
127 | } | ||
128 | |||
129 | #if 1 | ||
130 | char * mailstream_read_multiline(mailstream * s, size_t size, | ||
131 | MMAPString * stream_buffer, | ||
132 | MMAPString * multiline_buffer, | ||
133 | size_t progr_rate, | ||
134 | progress_function * progr_fun) | ||
135 | { | ||
136 | size_t count; | ||
137 | char * line; | ||
138 | size_t last; | ||
139 | |||
140 | if (mmap_string_assign(multiline_buffer, "") == NULL) | ||
141 | return NULL; | ||
142 | |||
143 | count = 0; | ||
144 | last = 0; | ||
145 | |||
146 | while ((line = mailstream_read_line_remove_eol(s, stream_buffer)) != NULL) { | ||
147 | if (mailstream_is_end_multiline(line)) | ||
148 | return multiline_buffer->str; | ||
149 | |||
150 | if (line[0] == '.') { | ||
151 | if (mmap_string_append(multiline_buffer, line + 1) == NULL) | ||
152 | return NULL; | ||
153 | } | ||
154 | else { | ||
155 | if (mmap_string_append(multiline_buffer, line) == NULL) | ||
156 | return NULL; | ||
157 | } | ||
158 | if (mmap_string_append(multiline_buffer, "\r\n") == NULL) | ||
159 | return NULL; | ||
160 | |||
161 | count += strlen(line); | ||
162 | if ((size != 0) && (progr_rate != 0) && (progr_fun != NULL)) | ||
163 | if (count - last >= progr_rate) { | ||
164 | (* progr_fun)(count, size); | ||
165 | last = count; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | return NULL; | ||
170 | } | ||
171 | |||
172 | #else | ||
173 | |||
174 | /* | ||
175 | high speed but don't replace the line break with '\n' and neither | ||
176 | remove the '.' | ||
177 | */ | ||
178 | |||
179 | static gboolean end_of_multiline(const char * str, gint len) | ||
180 | { | ||
181 | gint index; | ||
182 | |||
183 | index = len - 1; | ||
184 | |||
185 | if (str[index] != '\n') | ||
186 | return FALSE; | ||
187 | if (index == 0) | ||
188 | return FALSE; | ||
189 | |||
190 | index --; | ||
191 | |||
192 | if (str[index] == '\r') { | ||
193 | index --; | ||
194 | if (index == 0) | ||
195 | return FALSE; | ||
196 | } | ||
197 | |||
198 | if (str[index] != '.') | ||
199 | return FALSE; | ||
200 | if (index == 0) | ||
201 | return FALSE; | ||
202 | |||
203 | index--; | ||
204 | |||
205 | if (str[index] != '\n') | ||
206 | return FALSE; | ||
207 | |||
208 | return TRUE; | ||
209 | } | ||
210 | |||
211 | char * mailstream_read_multiline(mailstream * stream, size_t size, | ||
212 | MMAPString * stream_buffer, | ||
213 | MMAPString * line, | ||
214 | size_t progr_rate, | ||
215 | progress_function * progr_fun) | ||
216 | { | ||
217 | if (stream == NULL) | ||
218 | return NULL; | ||
219 | |||
220 | mmap_string_assign(line, ""); | ||
221 | |||
222 | do { | ||
223 | if (stream->read_buffer_len > 0) { | ||
224 | size_t i; | ||
225 | |||
226 | i = 0; | ||
227 | while (i < stream->read_buffer_len) { | ||
228 | if (end_of_multiline(stream->read_buffer, i + 1)) | ||
229 | return mailstream_read_len_append(stream, line, i + 1); | ||
230 | i++; | ||
231 | } | ||
232 | if (mailstream_read_len_append(stream, line, | ||
233 | stream->read_buffer_len) == NULL) | ||
234 | return NULL; | ||
235 | if (end_of_multiline(line->str, line->len)) | ||
236 | return line->str; | ||
237 | } | ||
238 | else | ||
239 | if (mailstream_feed_read_buffer(stream) == -1) | ||
240 | return NULL; | ||
241 | } | ||
242 | while (1); | ||
243 | |||
244 | return line->str; | ||
245 | } | ||
246 | #endif | ||
247 | |||
248 | |||
249 | |||
250 | static ssize_t send_data_line(mailstream * s, const char * line, size_t length) | ||
251 | { | ||
252 | int fix_eol; | ||
253 | const char * start; | ||
254 | size_t count; | ||
255 | |||
256 | start = line; | ||
257 | |||
258 | fix_eol = 0; | ||
259 | count = 0; | ||
260 | |||
261 | while (1) { | ||
262 | if (length == 0) | ||
263 | break; | ||
264 | |||
265 | if (* line == '\r') { | ||
266 | line ++; | ||
267 | |||
268 | count ++; | ||
269 | length --; | ||
270 | |||
271 | if (* line == '\n') { | ||
272 | line ++; | ||
273 | |||
274 | count ++; | ||
275 | length --; | ||
276 | |||
277 | break; | ||
278 | } | ||
279 | } | ||
280 | |||
281 | if (* line == '\n') { | ||
282 | line ++; | ||
283 | |||
284 | count ++; | ||
285 | length --; | ||
286 | |||
287 | fix_eol = 1; | ||
288 | break; | ||
289 | } | ||
290 | |||
291 | line ++; | ||
292 | length --; | ||
293 | count ++; | ||
294 | } | ||
295 | |||
296 | if (start[0] == '.') | ||
297 | if (mailstream_write(s, ".", 1) == -1) | ||
298 | goto err; | ||
299 | |||
300 | if (fix_eol) { | ||
301 | if (mailstream_write(s, start, count - 1) == -1) | ||
302 | goto err; | ||
303 | if (mailstream_write(s, "\r\n", 2) == -1) | ||
304 | goto err; | ||
305 | } | ||
306 | else { | ||
307 | if (mailstream_write(s, start, count) == -1) | ||
308 | goto err; | ||
309 | } | ||
310 | |||
311 | |||
312 | #if 0 | ||
313 | while (* line != '\n') { | ||
314 | if (* line == '\r') | ||
315 | pos = line; | ||
316 | if (* line == '\0') | ||
317 | return line; | ||
318 | if (mailstream_write(s, line, 1) == -1) | ||
319 | goto err; | ||
320 | line ++; | ||
321 | } | ||
322 | if (pos + 1 == line) { | ||
323 | if (mailstream_write(s, line, 1) == -1) | ||
324 | goto err; | ||
325 | } | ||
326 | else { | ||
327 | if (mailstream_write(s, "\r\n", 2) == -1) | ||
328 | goto err; | ||
329 | } | ||
330 | line ++; | ||
331 | #endif | ||
332 | |||
333 | return count; | ||
334 | |||
335 | err: | ||
336 | return -1; | ||
337 | } | ||
338 | |||
339 | int mailstream_send_data(mailstream * s, const char * message, | ||
340 | size_t size, | ||
341 | size_t progr_rate, | ||
342 | progress_function * progr_fun) | ||
343 | { | ||
344 | const char * current; | ||
345 | size_t count; | ||
346 | size_t last; | ||
347 | size_t remaining; | ||
348 | |||
349 | count = 0; | ||
350 | last = 0; | ||
351 | |||
352 | current = message; | ||
353 | remaining = size; | ||
354 | |||
355 | while (remaining > 0) { | ||
356 | ssize_t length; | ||
357 | |||
358 | length = send_data_line(s, current, remaining); | ||
359 | if (length < 0) | ||
360 | goto err; | ||
361 | |||
362 | current += length; | ||
363 | |||
364 | count += length; | ||
365 | if ((progr_rate != 0) && (progr_fun != NULL)) | ||
366 | if (count - last >= progr_rate) { | ||
367 | (* progr_fun)(count, size); | ||
368 | last = count; | ||
369 | } | ||
370 | |||
371 | remaining -= length; | ||
372 | } | ||
373 | if (mailstream_write(s, "\r\n.\r\n", 5) == -1) | ||
374 | goto err; | ||
375 | |||
376 | if (mailstream_flush(s) == -1) | ||
377 | goto err; | ||
378 | |||
379 | return 0; | ||
380 | |||
381 | err: | ||
382 | return -1; | ||
383 | } | ||