(msg_copy): Implement FSA described in RFC 934
Showing
1 changed file
with
43 additions
and
1 deletions
... | @@ -216,6 +216,18 @@ struct format_data { | ... | @@ -216,6 +216,18 @@ struct format_data { |
216 | mu_list_t format; | 216 | mu_list_t format; |
217 | }; | 217 | }; |
218 | 218 | ||
219 | /* State machine according to RFC 934: | ||
220 | |||
221 | S1 :: CRLF {CRLF} S1 | ||
222 | | "-" {"- -"} S2 | ||
223 | | c {c} S2 | ||
224 | |||
225 | S2 :: CRLF {CRLF} S1 | ||
226 | | c {c} S2 | ||
227 | */ | ||
228 | |||
229 | enum rfc934_state { S1, S2 }; | ||
230 | |||
219 | static int | 231 | static int |
220 | msg_copy (mu_message_t msg, mu_stream_t ostream) | 232 | msg_copy (mu_message_t msg, mu_stream_t ostream) |
221 | { | 233 | { |
... | @@ -223,6 +235,7 @@ msg_copy (mu_message_t msg, mu_stream_t ostream) | ... | @@ -223,6 +235,7 @@ msg_copy (mu_message_t msg, mu_stream_t ostream) |
223 | int rc; | 235 | int rc; |
224 | size_t n; | 236 | size_t n; |
225 | char buf[512]; | 237 | char buf[512]; |
238 | enum rfc934_state state = S1; | ||
226 | 239 | ||
227 | rc = mu_message_get_stream (msg, &istream); | 240 | rc = mu_message_get_stream (msg, &istream); |
228 | if (rc) | 241 | if (rc) |
... | @@ -231,7 +244,36 @@ msg_copy (mu_message_t msg, mu_stream_t ostream) | ... | @@ -231,7 +244,36 @@ msg_copy (mu_message_t msg, mu_stream_t ostream) |
231 | while (rc == 0 | 244 | while (rc == 0 |
232 | && mu_stream_sequential_read (istream, buf, sizeof buf, &n) == 0 | 245 | && mu_stream_sequential_read (istream, buf, sizeof buf, &n) == 0 |
233 | && n > 0) | 246 | && n > 0) |
234 | rc = mu_stream_sequential_write (ostream, buf, n); | 247 | { |
248 | size_t start, i; | ||
249 | |||
250 | for (i = start = 0; i < n; i++) | ||
251 | switch (state) | ||
252 | { | ||
253 | case S1: | ||
254 | if (buf[i] == '-') | ||
255 | { | ||
256 | rc = mu_stream_sequential_write (ostream, buf + start, | ||
257 | i - start + 1); | ||
258 | if (rc) | ||
259 | return rc; | ||
260 | rc = mu_stream_sequential_write (ostream, " -", 2); | ||
261 | if (rc) | ||
262 | return rc; | ||
263 | start = i + 1; | ||
264 | state = S2; | ||
265 | } | ||
266 | else if (buf[i] != '\n') | ||
267 | state = S2; | ||
268 | break; | ||
269 | |||
270 | case S2: | ||
271 | if (buf[i] == '\n') | ||
272 | state = S1; | ||
273 | } | ||
274 | if (i > start) | ||
275 | rc = mu_stream_sequential_write (ostream, buf + start, i - start); | ||
276 | } | ||
235 | return rc; | 277 | return rc; |
236 | } | 278 | } |
237 | 279 | ... | ... |
-
Please register or sign in to post a comment